(1) the statements above define a new type of record containing a string and a number
(2) an instance of that type can be created as
a = ex1("John", 34)
(3) the field names of ex1 can be listed with the function fieldnames
(4) the values of those fields can be retrieved as ex1.name or ex1.age
However, if another structure is defined as
struct ex2
data::NTuple{4, UInt8}
end
then
julia> b = ex2(0, 0, 0, 0)
ERROR: MethodError: no method matching ex2(::Int64, ::Int64, ::Int64, ::Int64)
Closest candidates are:
ex2(::Any) at REPL[1]:2
Stacktrace:
[1] top-level scope
@ REPL[3]:1
julia> b = ex2(0::UInt8, 0::UInt8, 0::UInt8, 0::UInt8)
ERROR: TypeError: in typeassert, expected UInt8, got a value of type Int64
Stacktrace:
[1] top-level scope
@ REPL[4]:1
Question 1: How do I define an instance of that ex2 data type with all values set to 0 as a UInt8 (or any other value, for that matter)? and why are those instantiation syntaxes problematic?
and
julia> fieldnames(ex2)
(:data,)
Question 2: How can I access individual values of ex2 since they have no apparent individual names?
The struct have one field, and if you check the constructor (with e.g. methods(ex2)) you see that it expects one argument – the tuple. You are passing 4 arguments. If you pass a tuple it works (and the Ints are converted to UInt8s, since the default constructor converts):
julia> struct ex2
data::NTuple{4, UInt8}
end
julia> a = ex2((1, 2, 3, 4)) # one argument, the tuple (1, 2, 3, 4)
ex2((0x01, 0x02, 0x03, 0x04))
You extract the tuple with .data, then use getindex:
Keep in mind though, that other behaviors you’d likely expect (such as iteration, length measurement, etc.) would also have to be implemented. There are some macros out there to help with defining these I believe, but I’m not familiar with them.
@uniment: Thanks for your input. My question arose in the context of writing a Julia wrapper for a C function, so I’ll try to remain as close as possible to the original code, but I’m always happy to learn something new. So, thanks a lot for that!