Zoeken…


Syntaxis

  • macro "string" # kort, string macro vorm
  • @macro_str "string" # lange, regelmatige macrovorm
  • macro`command`

Opmerkingen

Tekenreeksmacro's zijn niet zo krachtig als gewone oude tekenreeksen - omdat interpolatie moet worden geïmplementeerd in de logica van de macro, kunnen tekenreeksmacro's geen tekenreeksliteralen van hetzelfde scheidingsteken bevatten voor interpolatie.

Bijvoorbeeld, hoewel

julia> "$("x")"
"x"

werkt, de string macrotekstvorm

julia> doc"$("x")"
ERROR: KeyError: key :x not found

wordt onjuist ontleed. Dit kan enigszins worden beperkt door drievoudige aanhalingstekens te gebruiken als het scheidingsteken voor de buitenste tekenreeks;

julia> doc"""$("x")"""
"x"

werkt inderdaad naar behoren.

Stringmacro's gebruiken

Stringmacro's zijn syntactische suiker voor bepaalde macro-aanroepen. De parser vergroot de syntaxis zoals

mymacro"my string"

in

@mymacro_str "my string"

die dan, net als elke andere macro-aanroep, wordt vervangen door elke expressie die de macro @mymacro_str retourneert. Base Julia wordt geleverd met verschillende tekenreeksmacro's, zoals:

@b_str

Deze tekenreeksmacro construeert byte- arrays in plaats van tekenreeksen . De inhoud van de tekenreeks, gecodeerd als UTF-8, wordt gebruikt als de reeks bytes. Dit kan handig zijn voor de koppeling met low-level API's, waarvan vele werken met byte-arrays in plaats van tekenreeksen.

julia> b"Hello World!"
12-element Array{UInt8,1}:
 0x48
 0x65
 0x6c
 0x6c
 0x6f
 0x20
 0x57
 0x6f
 0x72
 0x6c
 0x64
 0x21

@big_str

Deze macro retourneert een BigInt of een BigFloat ontleend aan de gegeven string.

julia> big"1"
1

julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000

Deze macro bestaat omdat big(0.1) zich niet gedraagt zoals je in eerste instantie zou verwachten: de 0.1 is een Float64 benadering van echte 0.1 ( 1//10 ) en het promoten van dat naar BigFloat zal de benaderingsfout van Float64 . Het gebruik van de macro zal 0.1 rechtstreeks naar een BigFloat , waardoor de benaderingsfout wordt verminderd.

julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01

julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

@doc_str

Deze tekenreeksmacro construeert Base.Markdown.MD objecten, die in het interne documentatiesysteem worden gebruikt om rich- Base.Markdown.MD voor elke omgeving te bieden. Deze MD-objecten worden goed weergegeven in een terminal:

terminal markdown documentatie wordt goed weergegeven

en ook in een browser:

browser opmaak documentatie wordt goed weergegeven

@html_str

Deze tekenreeksmacro construeert HTML-tekenreeksliteralen, die mooi worden weergegeven in een browser:

html string macro-weergave mooi in een browser

@ip_str

Deze tekenreeksmacro construeert IP-adresliteralen. Het werkt met zowel IPv4 als IPv6:

julia> ip"127.0.0.1"
ip"127.0.0.1"

julia> ip"::"
ip"::"

@r_str

Deze tekenreeksmacro construeert Regex literalen .

@s_str

Deze tekenreeksmacro construeert SubstitutionString literals, die samenwerken met Regex literals om meer geavanceerde tekstuele substitutie mogelijk te maken.

@text_str

Deze tekenreeksmacro is qua geest vergelijkbaar met @doc_str en @html_str , maar heeft geen fancy opmaakfuncties:

platte tekst in de browser

@v_str

Deze tekenreeksmacro construeert VersionNumber literalen. Zie Versienummers voor een beschrijving van wat ze zijn en hoe ze te gebruiken.

@MIME_str

Deze tekenreeksmacro construeert de singleton-typen MIME-typen. MIME"text/plain" is bijvoorbeeld het type MIME("text/plain") .

Symbolen die geen wettelijke identificatie zijn

Julia Symbol-literalen moeten wettelijke identificatiegegevens zijn. Dit werkt:

julia> :cat
:cat

Maar dit betekent niet:

julia> :2cat
ERROR: MethodError: no method matching *(::Int64, ::Base.#cat)
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:288
  *{T<:Union{Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(::T<:Union{Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}, ::T<:Union{Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}) at int.jl:33
  *(::Real, ::Complex{Bool}) at complex.jl:180
  ...

Wat hier als een letterlijke symbool lijkt, wordt eigenlijk ontleed als een impliciete vermenigvuldiging van :2 (wat slechts 2 ) en de functie cat , die duidelijk niet werkt.

We kunnen gebruiken

julia> Symbol("2cat")
Symbol("2cat")

om het probleem te omzeilen.

Een tekenreeksmacro kan helpen om dit korter te maken. Als we de macro @sym_str definiëren:

macro sym_str(str)
    Meta.quot(Symbol(str))
end

dan kunnen we het gewoon doen

julia> sym"2cat"
Symbol("2cat")

om symbolen te maken die geen geldige Julia-ID's zijn.

Natuurlijk kunnen deze technieken ook symbolen die geldig Julia identifiers te creëren. Bijvoorbeeld,

julia> sym"test"
:test

Interpolatie implementeren in een tekenreeksmacro

Stringmacro's worden niet geleverd met ingebouwde interpolatiefaciliteiten . Het is echter mogelijk om deze functionaliteit handmatig te implementeren. Merk op dat het niet mogelijk is om in te sluiten zonder te ontsnappen aan stringliterals die hetzelfde scheidingsteken hebben als de omringende stringmacro; dat wil zeggen, hoewel """ $("x") """ mogelijk is, " $("x") " niet. In plaats daarvan moet dit worden ontsnapt als " $(\"x\") " . Zie het opmerkingengedeelte voor meer informatie over deze beperking.

Er zijn twee benaderingen voor het handmatig implementeren van interpolatie: implementeer parsing handmatig of laat Julia de parsering uitvoeren. De eerste benadering is flexibeler, maar de tweede benadering is eenvoudiger.

Handmatig parseren

macro interp_str(s)
    components = []
    buf = IOBuffer(s)
    while !eof(buf)
        push!(components, rstrip(readuntil(buf, '$'), '$'))
        if !eof(buf)
            push!(components, parse(buf; greedy=false))
        end
    end
    quote
        string($(map(esc, components)...))
    end
end

Julia ontleden

macro e_str(s)
    esc(parse("\"$(escape_string(s))\""))
end

Deze methode ontsnapt aan de string (maar escape_string er rekening mee dat escape_string niet aan de $ -tekens ontsnapt) en geeft deze terug aan de parser van Julia om te parseren. Ontsnappen aan de string is noodzakelijk om ervoor te zorgen dat " en \ geen invloed hebben op het parseren van de string. De resulterende expressie is een :string uitdrukking, die kan worden onderzocht en ontleed voor macro-doeleinden.

Opdrachtmacro's

0.6.0-dev

In Julia v0.6 en hoger worden opdrachtmacro's ondersteund naast reguliere tekenreeksmacro's. Een opdracht macro-aanroep zoals

mymacro`xyz`

wordt ontleed als de macro-aanroep

@mymacro_cmd "xyz"

Merk op dat dit vergelijkbaar is met tekenreeksmacro's, behalve met _cmd plaats van _str .

Wij gebruiken meestal de opdracht macro's voor code, die in vele talen bevat vaak " maar zelden bevat ` Zo is het vrij eenvoudig om een eenvoudige versie van herimplementeren. Quasiquoting behulp van command-macro's:

macro julia_cmd(s)
    esc(Meta.quot(parse(s)))
end

We kunnen deze macro inline gebruiken:

julia> julia`1+1`
:(1 + 1)

julia> julia`hypot2(x,y)=x^2+y^2`
:(hypot2(x,y) = begin  # none, line 1:
            x ^ 2 + y ^ 2
        end)

of multiline:

julia> julia```
       function hello()
           println("Hello, World!")
       end
       ```
:(function hello() # none, line 2:
        println("Hello, World!")
    end)

Interpolatie met $ wordt ondersteund:

julia> x = 2
2

julia> julia`1 + $x`
:(1 + 2)

maar de hier gegeven versie staat slechts één expressie toe:

julia> julia```
       x = 2
       y = 3
       ```
ERROR: ParseError("extra token after end of expression")

Het is echter niet moeilijk om het uit te breiden om meerdere expressies aan te kunnen.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow