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:

Terminal Markdown-Dokumentation wird gut dargestellt

und auch in einem Browser:

Browser-Markdown-Dokumentation wird gut dargestellt

@html_str

Dieses Zeichenfolgenmakro erstellt HTML-Zeichenfolgenliterale, die in einem Browser gut dargestellt werden:

HTML-String-Makro-Rendering in einem Browser

@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:

Klartext im Browser

@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

0,6,0-dev

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.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow