Julia Language
Strängmakroer
Sök…
Syntax
- makro "sträng" # kort, sträng makroform
- @macro_str "string" # lång, vanlig makroform
- macro`command`
Anmärkningar
Strängmakron är inte lika kraftfulla som vanliga gamla strängar - eftersom interpolering måste implementeras i makroens logik kan strängmakron inte innehålla strängbokstäver av samma avgränsare för interpolering.
Till exempel, även om
julia> "$("x")"
"x"
fungerar, strängen makro textform
julia> doc"$("x")"
ERROR: KeyError: key :x not found
tolkas felaktigt. Detta kan mildras något genom att använda trippeltecken som den yttre strängavgränsaren;
julia> doc"""$("x")"""
"x"
fungerar verkligen ordentligt.
Använd strängmakron
Strängmakroer är syntaktiskt socker för vissa makroinokationer. Tolkaren utvidgar syntaxen som
mymacro"my string"
in i
@mymacro_str "my string"
som sedan, liksom alla andra makroanrop, ersätts med vilket uttryck @mymacro_str
returnerar. Base Julia kommer med flera strängmakron, till exempel:
@b_str
Denna strängmakro konstruerar byte- matriser i stället för strängar . Innehållet i strängen, kodad som UTF-8, kommer att användas som matrisen för byte. Detta kan vara användbart för gränssnitt med API: er på låg nivå, av vilka många arbetar med byte-arrayer istället för strängar.
julia> b"Hello World!"
12-element Array{UInt8,1}:
0x48
0x65
0x6c
0x6c
0x6f
0x20
0x57
0x6f
0x72
0x6c
0x64
0x21
@big_str
Detta makro kommer att returnera en BigInt
eller en BigFloat
analyserad från den sträng som den har gett.
julia> big"1"
1
julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000
Detta makro existerar eftersom big(0.1)
inte uppför sig som man ursprungligen kan förvänta sig: 0.1
är en Float64
approximation av sann 0.1
( 1//10
), och att främja det till BigFloat
kommer att behålla approximationsfelet för Float64
. Användning av makro kommer att para 0.1
direkt till en BigFloat
, vilket minskar approximationsfelet.
julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01
julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01
@doc_str
Denna strängmakro konstruerar Base.Markdown.MD
objekt som används i det interna dokumentationssystemet för att tillhandahålla riktextdokumentation för alla miljöer. Dessa MD-objekt återges bra i en terminal:
och även i en webbläsare:
@html_str
Denna strängmakro konstruerar HTML-strängbokstäver, som återges fint i en webbläsare:
@ip_str
Denna strängmakro konstruerar IP-adressbokstäver. Det fungerar med både IPv4 och IPv6:
julia> ip"127.0.0.1"
ip"127.0.0.1"
julia> ip"::"
ip"::"
@r_str
Denna strängmakro konstruerar Regex
bokstäver .
@s_str
Denna strängmakro konstruerar SubstitutionString
bokstäver, som arbetar tillsammans med Regex
bokstäver för att möjliggöra mer avancerad textsubstitution.
@text_str
Denna strängmakro liknar i anda @doc_str
och @html_str
, men har inga snygga formateringsfunktioner:
@v_str
Denna strängmakro konstruerar VersionNumber
bokstäver. Se Versionsnummer för en beskrivning av vad de är och hur man använder dem.
@MIME_str
Denna strängmakro konstruerar singleton-typer av MIME-typer. Till exempel är MIME"text/plain"
typen av MIME("text/plain")
.
Symboler som inte är juridiska identifierare
Julia Symbol-bokstäver måste vara juridiska identifierare. Det här fungerar:
julia> :cat
:cat
Men detta gör inte:
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
...
Det som ser ut som en symbol bokstavlig här faktiskt är analyseras som en implicit multiplikation av :2
(vilket är bara 2
) och funktions cat
, vilket naturligtvis inte fungerar.
Vi kan använda
julia> Symbol("2cat")
Symbol("2cat")
att lösa problemet.
Ett strängmakro kan hjälpa till att göra detta mer spänt. Om vi definierar @sym_str
:
macro sym_str(str)
Meta.quot(Symbol(str))
end
då kan vi helt enkelt göra det
julia> sym"2cat"
Symbol("2cat")
för att skapa symboler som inte är giltiga Julia-identifierare.
Naturligtvis kan dessa tekniker också skapa symboler som är giltiga Julia-identifierare. Till exempel,
julia> sym"test"
:test
Implementering av interpolering i en strängmakro
Strängmakron levereras inte med inbyggda interpoleringsanläggningar . Det är dock möjligt att manuellt implementera denna funktion. Observera att det inte är möjligt att bädda in utan att undgå strängbokstäver som har samma avgränsare som den omgivande strängmakroen; det är, även om """ $("x") """
är möjligt, " $("x") "
inte är det. Istället måste detta undvikas som " $(\"x\") "
. Se kommentaravsnittet för mer information om denna begränsning.
Det finns två sätt att implementera interpolering manuellt: implementera parsing manuellt, eller få Julia att göra parsing. Den första metoden är mer flexibel, men den andra metoden är enklare.
Manuell tolkning
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 parsing
macro e_str(s)
esc(parse("\"$(escape_string(s))\""))
end
Denna metod slipper strängen (men observera att escape_string
inte undviker $
-tecknen) och skickar den tillbaka till Julias parser för att analysera. Att fly undan strängen är nödvändig för att säkerställa att "
och \
inte påverkar strängens parsing. Det resulterande uttrycket är ett :string
, som kan undersökas och sönderdelas för makroändamål.
Kommandomakron
I Julia v0.6 och senare stöds kommandomakroer utöver vanliga strängmakron. En kommando makro invokning som
mymacro`xyz`
blir analyserad som makroanrop
@mymacro_cmd "xyz"
Observera att detta liknar strängmakron, utom med _cmd
istället för _str
.
Vi använder vanligtvis kommando makron för kod, som på många språk ofta innehåller "
men sällan innehåller `
Till exempel är det ganska enkelt att reimplement en enkel version av. Quasiquoting använda kommando makron:
macro julia_cmd(s)
esc(Meta.quot(parse(s)))
end
Vi kan använda detta makro antingen inline:
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)
eller multiline:
julia> julia```
function hello()
println("Hello, World!")
end
```
:(function hello() # none, line 2:
println("Hello, World!")
end)
Interpolering med $
stöds:
julia> x = 2
2
julia> julia`1 + $x`
:(1 + 2)
men den version som ges här tillåter bara ett uttryck:
julia> julia```
x = 2
y = 3
```
ERROR: ParseError("extra token after end of expression")
Att utöka det för att hantera flera uttryck är dock inte svårt.