Ricerca…


Sintassi

  • macro "stringa" # breve, forma macro di stringa
  • @macro_str "stringa" # lungo, normale modulo macro
  • macro`command`

Osservazioni

Le macro di stringa non sono altrettanto potenti delle semplici stringhe vecchie: poiché l'interpolazione deve essere implementata nella logica della macro, le macro di stringa non sono in grado di contenere valori letterali di stringa dello stesso delimitatore per l'interpolazione.

Ad esempio, anche se

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

funziona, la forma del testo macro della stringa

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

viene analizzato in modo errato. Questo può essere in qualche modo mitigato usando le virgolette triple come delimitatore di stringhe esterne;

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

funziona davvero correttamente.

Utilizzo di macro di stringa

Le macro di stringa sono zucchero sintattico per alcune invocazioni di macro. Il parser espande la sintassi come

mymacro"my string"

in

@mymacro_str "my string"

che poi, come qualsiasi altra macro chiamata, viene sostituita con qualsiasi espressione @mymacro_str macro @mymacro_str . Base Julia viene fornito con diverse macro di stringa, come ad esempio:

@b_str

Questa macro di stringhe costruisce array di byte invece di stringhe . Il contenuto della stringa, codificato come UTF-8, verrà utilizzato come matrice di byte. Questo può essere utile per l'interfacciamento con API di basso livello, molte delle quali funzionano con array di byte invece di stringhe.

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

@big_str

Questa macro restituirà un BigInt o un BigFloat analizzato dalla stringa fornita.

julia> big"1"
1

julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000

Questa macro esiste perché big(0.1) non si comporta come ci si aspetterebbe inizialmente: lo 0.1 è un'approssimazione Float64 di true 0.1 ( 1//10 ), e promuoverlo a BigFloat manterrà l'errore di approssimazione di Float64 . L'uso della macro analizzerà 0.1 direttamente su un BigFloat , riducendo l'errore di approssimazione.

julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01

julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

@doc_str

Questa macro di stringhe costruisce oggetti Base.Markdown.MD , che vengono utilizzati nel sistema di documentazione interno per fornire documentazione di testo completo per qualsiasi ambiente. Questi oggetti MD rendono bene in un terminale:

la documentazione di markdown del terminale rende bene

e anche in un browser:

la documentazione di markdown del browser rende bene

@html_str

Questa macro di stringhe costruisce letterali stringa HTML, che rendono bene in un browser:

la macro della stringa html viene visualizzata correttamente in un browser

@ip_str

Questa macro di stringhe costruisce letterali di indirizzo IP. Funziona con IPv4 e IPv6:

julia> ip"127.0.0.1"
ip"127.0.0.1"

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

@r_str

Questa macro di stringhe costruisce i valori letterali di Regex .

@s_str

Questa macro di stringhe costruisce letterali di SubstitutionString , che Regex con i letterali di Regex per consentire una sostituzione testuale più avanzata.

@text_str

Questa macro di stringa è simile nello spirito a @doc_str e @html_str , ma non ha alcuna caratteristica di formattazione:

testo normale nel browser

@v_str

Questa macro di stringhe costruisce valori letterali VersionNumber . Vedi i numeri di versione per una descrizione di cosa sono e come usarli.

@MIME_str

Questa macro di stringhe costruisce i tipi singleton di tipi MIME. Ad esempio, MIME"text/plain" è il tipo di MIME("text/plain") .

Simboli che non sono identificativi legali

I valori letterali del simbolo di Julia devono essere identificativi legali. Questo funziona:

julia> :cat
:cat

Ma questo non:

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
  ...

Ciò che sembra un letterale di simboli qui viene in realtà analizzato come una moltiplicazione implicita di :2 (che è solo 2 ) e la funzione cat , che ovviamente non funziona.

Possiamo usare

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

per aggirare il problema.

Una macro di stringhe potrebbe aiutare a renderlo più conciso. Se definiamo la macro @sym_str :

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

allora possiamo semplicemente fare

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

per creare simboli che non sono identificativi di Julia validi.

Naturalmente, queste tecniche possono anche creare simboli che sono identificativi di Julia validi. Per esempio,

julia> sym"test"
:test

Implementazione dell'interpolazione in una macro di stringhe

Le macro di stringa non vengono fornite con le funzioni di interpolazione incorporate. Tuttavia, è possibile implementare manualmente questa funzionalità. Si noti che non è possibile incorporare senza eseguire l'escape di stringhe letterali che hanno lo stesso delimitatore della macro di stringa circostante; vale a dire, sebbene """ $("x") """ sia possibile, " $("x") " non lo è. Invece, questo deve essere salvato come " $(\"x\") " . Vedere la sezione commenti per maggiori dettagli su questa limitazione.

Esistono due approcci per implementare l'interpolazione manualmente: implementare l'analisi manualmente o fare in modo che Julia esegua l'analisi. Il primo approccio è più flessibile, ma il secondo approccio è più semplice.

Analisi manuale

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 analizza

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

Questo metodo sfugge alla stringa (ma nota che escape_string non sfugge ai $ sign) e lo restituisce al parser di Julia per analizzarlo. L'escape della stringa è necessario per garantire che " e \ non influenzino l'analisi della stringa. L'espressione risultante è un'espressione :string , che può essere esaminata e scomposta per scopi macro.

Macro di comando

0.6.0-dev

In Julia v0.6 e successive, le macro di comando sono supportate in aggiunta alle normali macro di stringa. Un richiamo di macro di comando come

mymacro`xyz`

viene analizzato come la chiamata macro

@mymacro_cmd "xyz"

Si noti che questo è simile alle macro di stringa, tranne con _cmd invece di _str .

Normalmente usiamo macro di comandi per il codice, che in molte lingue spesso contiene " ma raramente contiene ` . Ad esempio, è abbastanza semplice reimplementare una versione semplice di quasiquoting usando le macro di comando:

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

Possiamo usare questa macro sia in linea:

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)

o multilinea:

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

L'interpolazione usando $ è supportata:

julia> x = 2
2

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

ma la versione qui fornita consente solo un'espressione:

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

Tuttavia, estenderlo per gestire più espressioni non è difficile.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow