How can I push data to a Type when the data has more fields than I want

I got this code:

struct Test
  rest::String
end

function returnTest(args...)
  return Test(args...)
end

returnTest("This will be the rest string", "excess data", "some more uneeded")
# How will it return Test("This will be the rest string") without the error of it trying to push data to fields that aren't  there

I’m a bit confused by your question, it this what you want:

function returnTest(args...) 
  return Test(args[1])
end

I want my code to be automated, it will work with way more data and there will be excessive fields there
So I want only the data that the type will accept to get pushed without an error.
the whole point of it is to not do

function returnTest(args...)
  return Test(args[1], args[2], args[3])
end

One way:

julia> struct MyTest
           a::Int
           b::Int
       end

julia> getargs(T) = [:(args[$i]) for i in 1:fieldcount(T)]
getargs (generic function with 1 method)

julia> @eval MyTest(args...) = MyTest($(getargs(MyTest)...))
MyTest

julia> MyTest(1, 2, 3, 4)
MyTest(1, 2)

julia> @code_warntype MyTest(1, 2, 3, 4)
Body::MyTest
1 1 ─ %1 = (Base.getfield)(args, 1, true)::Int64                                                                         β”‚β•» getindex
  β”‚   %2 = (Base.getfield)(args, 2, true)::Int64                                                                         β”‚β”‚
  β”‚   %3 = %new(Main.MyTest, %1, %2)::MyTest                                                                             β”‚β•» Type
  └──      return %3                                   

Probably an over-kill though, you can just use (args[1], args[2]) instead for your type, but the solution above can be generalized to multiple types, each with its own fieldcount as such:

julia> struct MyTest
           a::Int
           b::Int
       end

julia> struct MyTest2
           a::Int
           b::Int
           c::Int
       end

julia> getargs(T) = [:(args[$i]) for i in 1:fieldcount(T)]
getargs (generic function with 1 method)

julia> for T in (:MyTest, :MyTest2)
           @eval $T(args...) = $T($(getargs(eval(T))...))
       end

julia> MyTest(1, 2, 3, 4)
MyTest(1, 2)

julia> MyTest2(1, 2, 3, 4)
MyTest2(1, 2, 3)

1 Like

Hey, thank you for your time I managed to write this and it’s actually getting the work done

    function construct(userData)
        wantedFields = fieldnames(Self)
        data  = []

        for i in wantedFields
            field = i |> String
            push!(data, userData[field])
        end
        return Self(data...)
    end