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:

Dokumentation för terminalmarkdown görs bra

och även i en webbläsare:

Dokumentation för webbläsarmarkering görs bra

@html_str

Denna strängmakro konstruerar HTML-strängbokstäver, som återges fint i en webbläsare:

html-strängmakro-rendering 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:

ren text i webbläsaren

@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

0.6.0-dev

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.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow