飛び散ったクワーグのフィールドからキーワード引数を取得するにはどうすればよいですか?


9

のような関数シグネチャがある場合f(args...; kwargs...)、どのようにして特定のキーワードを取得できkwargsますか?ナイーブ入力 kwargs.xは機能しません:

julia> f(args...; kwargs...) = kwargs.x
f (generic function with 1 method)

julia> f(x=1)
ERROR: type Pairs has no field x
Stacktrace:
 [1] getproperty(::Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:x,),Tuple{Int64}}}, ::Symbol) at ./Base.jl:20
 [2] #f#7(::Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:x,),Tuple{Int64}}}, ::typeof(f)) at ./REPL[2]:1
 [3] (::var"#kw##f")(::NamedTuple{(:x,),Tuple{Int64}}, ::typeof(f)) at ./none:0
 [4] top-level scope at REPL[3]:1

この質問は、#helpdeskのJuliaLang Slackチャネルに表示されました。非常に役立つジュリアスラックへの自動招待については、https: //slackinvite.julialang.orgに入力するだけです

回答:


10

これが発生する理由は、スプラットされたキーワード引数がデフォルトで名前付きタプルに格納されないためです。それらがどのように格納されているかを見ることができます:

julia> g(;kwargs...) = kwargs
g (generic function with 1 method)

julia> g(a=1)
pairs(::NamedTuple) with 1 entry:
  :a => 1

julia> g(a=1) |> typeof
Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:a,),Tuple{Int64}}}

そのため、スプラッティングされたクワーグは代わりに、ある種のイテレーターオブジェクトとして格納されます。ただし、そのkwargsイテレータを次のようにNamedTuple に簡単に変換して、(;kwargs...)期待どおりにアクセスできるため、例を次のように変換できます。

julia> f(args...; kwargs...) = (;kwargs...).x
f (generic function with 1 method)

julia> f(x=1, y=2)
1

もちろん、これを行うためのより慣用的な方法は、代わりに次のように関数を記述することです。

julia> f(args...; x, kwargs...) = x
f (generic function with 1 method)

julia> f(x=1, y=2)
1

ただし、これはx、関数の作成時にアクセスしたい名前()がわかっていることを前提としています。


簡単な補足:の例に戻ると、次のようにして返されg(;kwargs...) = kwargsたイテレータオブジェクトのフィールド名を要求できます。

julia> g(x=1, y=2) |> typeof |> fieldnames
(:data, :itr)

うーん、このdataフィールドは何ですか?

julia> g(x=1, y=2).data
(x = 1, y = 2)

ああ!つまり、実際にそれを使用して名前付きタプルとしてクワーグを取得できます。つまりf(;kwargs...) = kwargs.data.x、動作しますが、ドキュメント化されていない動作に依存しているように思われるため、このアプローチはお勧めしません。 juliaのバージョン間。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.