Julia Language
Zeichenfolge-Makros
Suche…
Syntax
- Makro "Zeichenfolge" # kurz, Zeichenfolge Makroform
- @macro_str "string" # Lange, reguläre Makroform
- Makro`Befehl`
Bemerkungen
String-Makros sind nicht ganz so leistungsfähig wie einfache alte Strings. Da Interpolation in der Logik des Makros implementiert werden muss, können String-Makros keine String-Literale desselben Trennzeichens für die Interpolation enthalten.
Zum Beispiel obwohl
julia> "$("x")"
"x"
funktioniert, das String-Makro-Textformular
julia> doc"$("x")"
ERROR: KeyError: key :x not found
wird falsch analysiert. Dies kann durch die Verwendung von Anführungszeichen als Begrenzungszeichen für die äußeren Zeichenketten etwas gemildert werden.
julia> doc"""$("x")"""
"x"
funktioniert ja richtig.
String-Makros verwenden
String-Makros sind syntaktischer Zucker für bestimmte Makroaufrufe. Der Parser erweitert die Syntax wie
mymacro"my string"
in
@mymacro_str "my string"
Dieser wird dann wie jeder andere Makroaufruf durch einen beliebigen Ausdruck ersetzt, den das @mymacro_str
Makro zurückgibt. Base Julia verfügt über mehrere String-Makros wie:
@b_str
Dieses Zeichenfolgenmakro erstellt Byte- Arrays anstelle von Zeichenfolgen . Der Inhalt des Strings, der als UTF-8 codiert ist, wird als Byte-Array verwendet. Dies kann nützlich sein, um Schnittstellen mit APIs auf niedriger Ebene herzustellen, von denen viele mit Byte-Arrays anstelle von Zeichenfolgen arbeiten.
julia> b"Hello World!"
12-element Array{UInt8,1}:
0x48
0x65
0x6c
0x6c
0x6f
0x20
0x57
0x6f
0x72
0x6c
0x64
0x21
@big_str
Dieses Makro gibt ein BigInt
oder ein BigFloat
aus der angegebenen Zeichenfolge analysiert wird.
julia> big"1"
1
julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000
Dieses Makro ist vorhanden, weil sich big(0.1)
nicht so verhält, wie man es anfangs erwarten könnte: Die 0.1
ist eine Float64
Approximation von True 0.1
( 1//10
). BigFloat
das für BigFloat
wird der Approximationsfehler von Float64
. Bei Verwendung des Makros wird 0.1
direkt in ein BigFloat
, wodurch der Näherungsfehler reduziert wird.
julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01
julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01
@doc_str
Dieses Zeichenfolgenmakro erstellt Base.Markdown.MD
Objekte, die im internen Dokumentationssystem verwendet werden, um eine Rich-Text-Dokumentation für jede Umgebung bereitzustellen. Diese MD-Objekte werden in einem Terminal gut dargestellt:
und auch in einem Browser:
@html_str
Dieses Zeichenfolgenmakro erstellt HTML-Zeichenfolgenliterale, die in einem Browser gut dargestellt werden:
@ip_str
Dieses Zeichenfolgenmakro erstellt IP-Adressliterale. Es funktioniert sowohl mit IPv4 als auch mit IPv6:
julia> ip"127.0.0.1"
ip"127.0.0.1"
julia> ip"::"
ip"::"
@r_str
Dieses String-Makro erstellt Regex
Literale .
@s_str
Dieses Zeichenfolgenmakro erstellt SubstitutionString
, die mit Regex
Literalen zusammenarbeiten, um eine erweiterte Regex
zu ermöglichen.
@text_str
Dieses Zeichenfolgenmakro ähnelt im Sinne von @doc_str
und @html_str
, hat jedoch keine ausgefallenen Formatierungsfunktionen:
@v_str
Dieses Zeichenfolgenmakro erstellt VersionNumber
Literale. Siehe Versionsnummern für eine Beschreibung ihrer Verwendung und ihrer Verwendung.
@MIME_str
Dieses Zeichenfolgenmakro erstellt die Singleton-Typen von MIME-Typen. Beispielsweise ist MIME"text/plain"
der Typ von MIME("text/plain")
.
Symbole, die keine legalen Bezeichnungen sind
Julia-Symbol-Literale müssen gültige Bezeichner sein. Das funktioniert:
julia> :cat
:cat
Dies gilt jedoch nicht:
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
...
Was hier wie ein Symbolliteral aussieht, wird tatsächlich als implizite Multiplikation von :2
(was nur 2
) und der Funktion cat
analysiert, die offensichtlich nicht funktioniert.
Wir können benutzen
julia> Symbol("2cat")
Symbol("2cat")
um das Problem zu umgehen.
Ein String-Makro könnte dazu beitragen, dies knapper zu machen. Wenn wir das @sym_str
Makro definieren:
macro sym_str(str)
Meta.quot(Symbol(str))
end
dann können wir es einfach tun
julia> sym"2cat"
Symbol("2cat")
um Symbole zu erstellen, die keine gültigen Julia-Bezeichner sind.
Natürlich können diese Techniken auch Symbole erstellen, die gültige Julia-Bezeichner sind. Zum Beispiel,
julia> sym"test"
:test
Interpolation in einem String-Makro implementieren
String-Makros verfügen nicht über integrierte Interpolationsfunktionen . Es ist jedoch möglich, diese Funktionalität manuell zu implementieren. Beachten Sie, dass das Einbetten nicht möglich ist, ohne Stringliterale zu umgehen, die denselben Begrenzer wie das umgebende Stringmakro haben. Das heißt, obwohl """ $("x") """
möglich ist, " $("x") "
nicht. Stattdessen muss dies als " $(\"x\") "
. Weitere Informationen zu dieser Einschränkung finden Sie im Abschnitt " Anmerkungen" .
Es gibt zwei Ansätze zum manuellen Implementieren der Interpolation: Implementieren Sie das Parsing manuell oder lassen Sie Julia das Parsing durchführen. Der erste Ansatz ist flexibler, der zweite Ansatz ist jedoch einfacher.
Manuelle Analyse
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 beim Parsing
macro e_str(s)
esc(parse("\"$(escape_string(s))\""))
end
Diese Methode entgeht der Zeichenfolge (beachte jedoch, dass escape_string
die $
-Zeichen nicht entgeht) und gibt sie an Julias Parser zurück, um sie zu analysieren. Es ist notwendig, den String zu umgehen, um sicherzustellen, dass "
und \
die Analyse des Strings nicht beeinflussen. Der resultierende Ausdruck ist ein :string
Ausdruck, der für Makrozwecke untersucht und zerlegt werden kann.
Befehlsmakros
In Julia v0.6 und höher werden zusätzlich zu regulären Zeichenfolgenmakros Befehlsmakros unterstützt. Ein Befehlsmakroaufruf wie
mymacro`xyz`
wird als Makroaufruf analysiert
@mymacro_cmd "xyz"
Beachten Sie, dass dies den Zeichenfolgenmakros ähnelt, mit Ausnahme von _cmd
anstelle von _str
.
Wir verwenden in der Regel Befehlsmakros für Code, der in vielen Sprachen häufig enthält "
, aber selten enthält `
So ist es recht einfach , eine einfache Version neu zu implementieren. Quasiquoting mit Befehlsmakros:
macro julia_cmd(s)
esc(Meta.quot(parse(s)))
end
Wir können dieses Makro entweder inline verwenden:
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)
oder mehrzeilig:
julia> julia```
function hello()
println("Hello, World!")
end
```
:(function hello() # none, line 2:
println("Hello, World!")
end)
Interpolation mit $
wird unterstützt:
julia> x = 2
2
julia> julia`1 + $x`
:(1 + 2)
Die hier angegebene Version erlaubt jedoch nur einen Ausdruck:
julia> julia```
x = 2
y = 3
```
ERROR: ParseError("extra token after end of expression")
Die Erweiterung auf mehrere Ausdrücke ist jedoch nicht schwierig.