Joe Murphy
Joe Murphy

Reputation: 85

Struct literals in Julia

I'm working on a project where it would be very useful to be able to initialize anonymous structs (aka don't care what type they are) that have an arbitrary number of fields and values of type Any, all in one line.

Essentially I need a Dict, but with values that can be accessed using dot notation (I realize I could just use a Dict here, but I'm not the end user here).

Is there a way I could do this in Julia as it is or could I define some magical type (apparently now called a mutable struct) that has a crazy getfield() overload? I saw the PR on Github about overloading . which would also be cool, but I saw that it was likely not coming soon.

Thanks!

Upvotes: 3

Views: 1355

Answers (2)

Jeff Bezanson
Jeff Bezanson

Reputation: 3207

Try the NamedTuples package for this: https://github.com/blackrock/NamedTuples.jl We are also working on adding this to the language, so it can have nicer syntax and so we can be sure it will work in every case.

Upvotes: 2

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22215

If you're happy with your 'anonymous struct' being immutable (which I assume is the case since you use the word 'literals'), then you can simulate this with a closure, which can be constructed very straightforwardly via the let keyword:

julia> D = let a=1, b=2; () -> Any[a,b]; end
(::#1) (generic function with 1 method)

julia> fieldnames(D)
2-element Array{Symbol,1}:
 :b
 :a

julia> D()
2-element Array{Any,1}:
 1
 2

julia> D.a
1

julia> D.b
2

julia> (let a=1, b=2; () -> Any[a,b]; end).a
1

julia> (let a=1, b=2; () -> Any[a,b]; end).b
2

This works because closures capture their 'closed' variables as fields.


PS. More specifically, closures are implemented under the hood as callable types (or so I'm told :p)

PPS. For some reason, the fields in the closure are introduced in reverse order. If order matters to you (such that elements in fieldnames(D) and D() are in equivalent order), introduce the 'fields' in reverse order within the let declaration, e.g.: D = let c=3, b=2, a=1; () -> Any[a,b,c]; end.

PPPS. Alternatively, if you find this syntax ugly, you could always implement a "createAnonymousStruct" function that takes a Dictionary or something and returns such a closure

Upvotes: 3

Related Questions