Splatted kwargs alanından anahtar kelime bağımsız değişkenlerini nasıl alabilirim?


9

Gibi bir işlev imzam varsa f(args...; kwargs...), belirli bir anahtar kelimeyi nasıl alabilirim kwargs? Saf yazım kwargs.xçalışmıyor:

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

Bu soru #helpdesk'teki JuliaLang Slack kanalında göründü. Çok yardımcı olan Julia gevşekliğine otomatik bir davet için https://slackinvite.julialang.org

Yanıtlar:


10

Bunun gerçekleşmesinin nedeni, uyarılmış anahtar kelime bağımsız değişkenlerinin varsayılan olarak adlandırılmış bir grupta depolanmamasıdır. Nasıl depolandıklarını görebiliriz:

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

Böylece, sıçrayan kwargs bir çeşit yineleyici nesnesi olarak saklanır. Ancak, bu kwargsyineleyiciyi şöyle bir NamedTuple'e kolayca dönüştürebiliriz : (;kwargs...)ve sonra beklediğimiz şekilde erişebiliriz, böylece örneğiniz

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

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

Tabii ki, bunu yapmanın daha deyimsel yolu işlevi şöyle yazmaktır:

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

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

ancak bu x, işlevi yazarken erişmek istediğiniz adı ( ) bildiğinizi varsayar .


Kısa bir sidenote: Örneğimize g(;kwargs...) = kwargsdönersek, döndürülen yineleyici nesnesinin alan adlarını şu şekilde sorabiliriz:

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

Hm, bu dataalan nedir?

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

Aha! yani kwarg'ları f(;kwargs...) = kwargs.data.xbunu kullanarak adlandırılmış bir tuple olarak alabiliriz, yani işe yarayabilir, ancak belgelenmemiş davranışa bağlı olduğu için bu yaklaşımı tavsiye etmem, bu yüzden kararlı olması garanti edilmeyen sadece bir uygulama detayı olabilir julia sürümleri arasında.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.