산산조각 난 필드에서 키워드 인수를 어떻게 검색합니까?


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 채널에 나타납니다. 매우 유용한 Julia 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반복자를 쉽게 (;kwargs...)다음과 같이 NamedTuple 로 변환 한 다음 예상 한 방식으로 액세스 할 수 있습니다.

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과 같이 iterator 객체의 필드 이름을 요청할 수 있습니다.

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

흠,이 data분야 는 무엇 입니까?

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

아하! 그래서 우리는 실제로 그것을 사용하여 명명 된 튜플로 kwargs를 얻을 f(;kwargs...) = kwargs.data.x수 있습니다. 줄리아 버전.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.