Stream: helpdesk (published)

Topic: ✔ Not able to splat with @kwdef


view this post on Zulip Hannes (Nov 13 2022 at 22:18):

I'm trying to splat a Dict{Symbol, Any} into a struct that I created with @kwdef, it looks like I've defined the method: MyStruct(; abc), but it's not interpreting the splat as keyword arguments, instead as positional arguments.

julia> Base.@kwdef struct MyStruct
           abc::Int64
       end

julia> methods(MyStruct)
# 3 methods for type constructor:
[1] MyStruct(; abc) in Main at util.jl:493
[2] MyStruct(abc::Int64) in Main at Untitled-2:5
[3] MyStruct(abc) in Main at Untitled-2:5

julia> x = Dict(:abc=>123)

julia> MyStruct(x...)
ERROR: MethodError: Cannot `convert` an object of type Pair{Symbol, Int64} to an object of type Int64
Closest candidates are:
  convert(::Type{T}, ::T) where T<:Number at number.jl:6
  convert(::Type{T}, ::Number) where T<:Number at number.jl:7
  convert(::Type{T}, ::Base.TwicePrecision) where T<:Number at twiceprecision.jl:273
  ...
Stacktrace:
 [1] MyStruct(abc::Pair{Symbol, Int64})
   @ Main ./Untitled-2:5
 [2] top-level scope
   @ Untitled-2:11

view this post on Zulip Mason Protter (Nov 13 2022 at 22:19):

You need to do MyStruct(; x...) so that julia knows you're splatting as keyword aguments, not regular arguments

view this post on Zulip Mason Protter (Nov 13 2022 at 22:20):

julia> MyStruct(; x...)
MyStruct(123)

view this post on Zulip Mason Protter (Nov 13 2022 at 22:23):

Maybe this helps clear it up:

julia> f(x...) = println("got arguments: ", x);

julia> f(;x...) = println("got keyword arguments: ", x);

julia> f(x...)
got arguments: (:abc => 123,)

julia> f(;x...)
got keyword arguments: Base.Pairs(:abc => 123)

view this post on Zulip Hannes (Nov 13 2022 at 22:58):

Ah, of course, so obvious in hindsight! Thanks!

view this post on Zulip Notification Bot (Nov 13 2022 at 23:02):

Hannes has marked this topic as resolved.

view this post on Zulip Mason Protter (Nov 13 2022 at 23:13):

Happy to help :smile:

view this post on Zulip Mosè Giordano (Nov 14 2022 at 04:48):

My rule of thumb is: _always_ start keyword arguments with semicolon and you don't need to remember about these corner cases

view this post on Zulip jar (Nov 14 2022 at 04:50):

imho kwargs should require ;


Last updated: Nov 22 2024 at 04:41 UTC