Julia Language
文字列マクロ
サーチ…
構文
- マクロ "string"#短い、文字列マクロフォーム
- @macro_str "string"#長い、通常のマクロ形式
- マクロ `コマンド`
備考
文字列マクロは普通の古い文字列ほど強力ではありません。補間はマクロのロジックに実装する必要があるため、文字列マクロは補間のための同じ区切り文字の文字列リテラルを含むことができません。
例えば、
julia> "$("x")"
"x"
作品、文字列マクロテキスト形式
julia> doc"$("x")"
ERROR: KeyError: key :x not found
間違って解析されます。これは外側の文字列区切り記号として3重引用符を使用することによって幾分軽減できます。
julia> doc"""$("x")"""
"x"
確かに正しく動作します。
文字列マクロの使用
文字列マクロは、特定のマクロ呼び出しの構文的な砂糖です。パーサーは次のような構文を展開します。
mymacro"my string"
に
@mymacro_str "my string"
他のマクロ呼び出しと同様に、 @mymacro_str
マクロが返す式で置き換えられます。 Base Juliaには、以下のようないくつかの文字列マクロが付属しています。
@b_str
この文字列マクロは、 文字 列ではなくバイト配列を構成します 。 UTF-8としてエンコードされた文字列の内容は、バイトの配列として使用されます。これは、低レベルのAPIとのインタフェースに役立ちます。これらのAPIの多くは、文字列ではなくバイト配列で動作します。
julia> b"Hello World!"
12-element Array{UInt8,1}:
0x48
0x65
0x6c
0x6c
0x6f
0x20
0x57
0x6f
0x72
0x6c
0x64
0x21
@big_str
このマクロは戻りますBigInt
またはBigFloat
それが与えられています文字列から解析を。
julia> big"1"
1
julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000
ので、このマクロは存在するbig(0.1)
:1は、最初は期待通りに動作しない0.1
あるFloat64
真の近似値0.1
( 1//10
)、およびにそれを促進BigFloat
の近似誤差続けるFloat64
。マクロを使用するとBigFloat
0.1
直接解析され、近似誤差が小さくなります。
julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01
julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01
@doc_str
この文字列マクロは、 Base.Markdown.MD
オブジェクトを構築します。このオブジェクトは、内部のドキュメントシステムで使用され、あらゆる環境のリッチテキストドキュメントを提供します。これらのMDオブジェクトは、端末でうまくレンダリングされます。
また、ブラウザでも:
@html_str
この文字列マクロは、HTML文字列リテラルを構築します。これは、ブラウザでうまく表現できます。
@ip_str
この文字列マクロはIPアドレスリテラルを構成します。これはIPv4とIPv6の両方で動作します:
julia> ip"127.0.0.1"
ip"127.0.0.1"
julia> ip"::"
ip"::"
@r_str
この文字列マクロはRegex
リテラルを構成します 。
@s_str
この文字列マクロはSubstitutionString
リテラルを構成します。このリテラルはRegex
リテラルと一緒に機能し、より高度なテキスト置換を可能にします。
@text_str
この文字列マクロは、 @doc_str
および@html_str
と似ていますが、派手な書式設定機能はありません。
@v_str
この文字列マクロは、 VersionNumber
リテラルを構築します。 バージョンとバージョンの詳細については、 バージョン番号を参照してください。
@MIME_str
この文字列マクロは、シングルトンタイプのMIMEタイプを構築します。例えば、 MIME"text/plain"
はMIME("text/plain")
のタイプです。
正当な識別子ではないシンボル
Julia Symbolリテラルは正当な識別子でなければなりません。これは動作します:
julia> :cat
:cat
しかし、これはしません:
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
...
ここでシンボルリテラルのように見えるのは、実際には:2
(これはちょうど2
)と関数cat
暗黙的な乗算として解析されています。これは明らかに機能しません。
我々は使用することができます
julia> Symbol("2cat")
Symbol("2cat")
問題を回避する
文字列マクロは、これをより簡潔にするのに役立ちます。 @sym_str
マクロを定義した場合:
macro sym_str(str)
Meta.quot(Symbol(str))
end
私たちは単に行うことができます
julia> sym"2cat"
Symbol("2cat")
有効なジュリア識別子ではないシンボルを作成する。
もちろん、これらの手法は、有効なジュリア識別子であるシンボルを作成することもできます。例えば、
julia> sym"test"
:test
文字列マクロ内での補間の実装
文字列マクロには補間機能が組み込まれていません。ただし、この機能を手動で実装することは可能です。周囲の文字列マクロと同じ区切り文字を持つ文字列リテラルをエスケープしないと埋め込むことはできません。つまり、 """ $("x") """
は可能ですが、 " $("x") "
はできません。代わりに、これは" $(\"x\") "
としてエスケープする必要があります。この制限の詳細については、「 備考 」を参照してください。
手動で補間を実装するには、2つの方法があります。手動で解析を実装するか、Juliaに解析を実行させます。最初のアプローチはより柔軟ですが、2番目のアプローチは簡単です。
手動解析
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
ジュリアパース
macro e_str(s)
esc(parse("\"$(escape_string(s))\""))
end
このメソッドは文字列をエスケープします(しかし、 escape_string
は$
記号をエスケープしません )、それを解析するためにJuliaのパーサに渡します。 "
と\
が文字列の解析に影響を与えないようにするには、文字列をエスケープする必要があります。結果の式は:string
式で、マクロ目的で調べて分解できます。
コマンドマクロ
Julia v0.6以降では、通常の文字列マクロに加えてコマンドマクロもサポートされています。のようなコマンドマクロ呼び出し
mymacro`xyz`
マクロ呼び出しとして解析される
@mymacro_cmd "xyz"
_cmd
代わりに_str
を除いて、これは文字列マクロに似ています。
私たちは通常、多くの言語で"
しばしば含まれていますが、まれに含まれている"
コードにコマンドマクロを使用します。たとえば、コマンドマクロを使用して簡単なバージョンの準 `
を再実装するのはかなり簡単です。
macro julia_cmd(s)
esc(Meta.quot(parse(s)))
end
このマクロはインラインで使うことができます:
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)
または複数行:
julia> julia```
function hello()
println("Hello, World!")
end
```
:(function hello() # none, line 2:
println("Hello, World!")
end)
$
を使用した補間がサポートされています:
julia> x = 2
2
julia> julia`1 + $x`
:(1 + 2)
ここで与えられたバージョンは1つの式しか許されません:
julia> julia```
x = 2
y = 3
```
ERROR: ParseError("extra token after end of expression")
しかし、それを拡張して複数の式を処理することは難しくありません。