Szukaj…


Składnia

  • makro „string” # krótki, forma makra string
  • @macro_str "string" # długi, regularny formularz makra
  • makro`command`

Uwagi

Makra łańcuchowe nie są tak potężne jak zwykłe stare łańcuchy - ponieważ interpolacja musi być zaimplementowana w logice makra, makra łańcuchowe nie mogą zawierać literałów łańcuchowych tego samego separatora do interpolacji.

Na przykład chociaż

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

działa, formularz tekstowy makro ciąg

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

jest nieprawidłowo analizowany. Można to nieco złagodzić, używając potrójnych cudzysłowów jako zewnętrznego ogranicznika łańcucha;

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

naprawdę działa poprawnie.

Używanie makr łańcuchowych

Makra łańcuchowe są cukrem syntaktycznym dla niektórych wywołań makr. Analizator składni rozszerza składnię jak

mymacro"my string"

w

@mymacro_str "my string"

który następnie, jak każde inne wywołanie makra, zostaje zastąpiony dowolnym wyrażeniem @mymacro_str makro @mymacro_str . Baza Julia zawiera kilka makr łańcuchowych, takich jak:

@b_str

To makro ciągów konstruuje tablice bajtów zamiast ciągów . Zawartość łańcucha, zakodowanego jako UTF-8, będzie używana jako tablica bajtów. Może to być przydatne w przypadku interfejsów API niskiego poziomu, z których wiele działa z tablicami bajtów zamiast ciągów.

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

@big_str

To makro zwróci BigInt lub BigFloat parsowane z podanego ciągu.

julia> big"1"
1

julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000

To makro istnieje, ponieważ big(0.1) nie zachowuje się tak, jak można się początkowo spodziewać: 0.1 jest przybliżeniem Float64 wartości 0.1 ( 1//10 ), a promowanie go do BigFloat spowoduje zachowanie błędu przybliżenia Float64 . Użycie makra BigFloat 0.1 bezpośrednio do BigFloat , zmniejszając błąd aproksymacji.

julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01

julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

@doc_str

To makro ciągów konstruuje obiekty Base.Markdown.MD , które są używane w wewnętrznym systemie dokumentacji do dostarczania dokumentacji tekstowej dla dowolnego środowiska. Te obiekty MD dobrze renderują się w terminalu:

dokumentacja przeceny terminala dobrze się renderuje

a także w przeglądarce:

dokumentacja przeceny przeglądarki renderuje się dobrze

@html_str

To makro ciągów tworzy literały ciągów HTML, które ładnie renderują się w przeglądarce:

ładnie renderowane makro ciągu znaków HTML w przeglądarce

@ip_str

To makro ciągu konstruuje literały adresu IP. Działa zarówno z IPv4, jak i IPv6:

julia> ip"127.0.0.1"
ip"127.0.0.1"

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

@r_str

To makro łańcuchowe tworzy literały Regex .

@s_str

To makro łańcuchowe konstruuje literały SubstitutionString , które współpracują z literałami Regex aby umożliwić bardziej zaawansowane podstawianie tekstu.

@text_str

To makro ciągu jest podobne w duchu do @doc_str i @html_str , ale nie ma żadnych fantazyjnych funkcji formatowania:

zwykły tekst w przeglądarce

@v_str

To makro ciągu konstruuje literały VersionNumber . Zobacz Numery wersji, aby uzyskać opis tego, czym są i jak z nich korzystać.

@MIME_str

To makro łańcuchowe konstruuje typy singletonów typów MIME. Na przykład MIME"text/plain" jest typem MIME("text/plain") .

Symbole, które nie są prawnymi identyfikatorami

Literały Julia Symbol muszą być prawnymi identyfikatorami. To działa:

julia> :cat
:cat

Ale to nie:

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

To, co wygląda tutaj na dosłowny symbol, jest w rzeczywistości analizowane jako ukryte mnożenie :2 (czyli tylko 2 ) i funkcji cat , która oczywiście nie działa.

Możemy użyć

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

obejść ten problem.

Makro ciągu może pomóc uczynić to bardziej zwięzłym. Jeśli zdefiniujemy makro @sym_str :

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

wtedy możemy po prostu zrobić

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

do tworzenia symboli, które nie są prawidłowymi identyfikatorami Julii.

Oczywiście techniki te mogą również tworzyć symbole, które ważnymi identyfikatorami Julii. Na przykład,

julia> sym"test"
:test

Implementowanie interpolacji w makrze ciągów

Makra łańcuchowe nie są dostarczane z wbudowanymi funkcjami interpolacji . Możliwe jest jednak ręczne wdrożenie tej funkcji. Zauważ, że nie jest możliwe osadzanie bez znaków literowych łańcucha, które mają ten sam separator, co otaczające makro łańcucha; to znaczy, chociaż """ $("x") """ jest możliwe, " $("x") " nie jest możliwe. Zamiast tego musi być poprzedzony znakiem " $(\"x\") " . Więcej informacji na temat tego ograniczenia znajduje się w sekcji uwag .

Istnieją dwa podejścia do ręcznej implementacji interpolacji: ręczne analizowanie składni lub zlecenie Julii wykonania analizy. Pierwsze podejście jest bardziej elastyczne, ale drugie podejście jest łatwiejsze.

Parsowanie ręczne

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 analizuje

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

Ta metoda unika ciągu znaków (ale należy pamiętać, że escape_string nie ucieka znakom $ ) i przekazuje go z powrotem do analizatora składni Julii w celu przetworzenia. Ucieczka łańcucha jest niezbędna, aby upewnić się, że " i \ nie wpływają na parsowanie łańcucha. Wynikiem tego jest wyrażenie :string , które można badać i rozkładać w celach makro.

Makra poleceń

0.6.0-dev

W Julii v0.6 i nowszych makra poleceń są obsługiwane oprócz zwykłych makr łańcuchowych. Wywołanie makra polecenia jak

mymacro`xyz`

jest analizowany jako wywołanie makra

@mymacro_cmd "xyz"

Zauważ, że jest to podobne do makr łańcuchowych, z wyjątkiem _cmd zamiast _str .

Zwykle używamy makr poleceń do kodu, który w wielu językach często zawiera " ale rzadko zawiera ` . Na przykład dość łatwo jest zaimplementować prostą wersję quasi-cytowania za pomocą makr poleceń:

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

Możemy użyć tego makra albo bezpośrednio:

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)

lub multilinii:

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

Obsługiwana jest interpolacja za pomocą $ :

julia> x = 2
2

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

ale podana tutaj wersja dopuszcza tylko jedno wyrażenie:

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

Jednak rozszerzenie go na obsługę wielu wyrażeń nie jest trudne.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow