Using structs in for loops?

Hey guys

Can anyone explain to me why k is not defined in this case?

struct MyStruct
    id::Int
     x::Float64
     y::Float64
end

function SquareGrid(nStart,nEnd,nStep)
    x  = collect(range(nStart,nEnd, step=nStep))
    nP = size(x)[1]
    for i = 1:nP
        k = MyStruct(i,x[i],x[i])
        println(k)
    end
    return k
end

It gives me the error:

ERROR: UndefVarError: k not defined
Stacktrace:
 [1] SquareGrid(::Int64, ::Int64, ::Float64) at C:\Users\Ahmed Salih\OneDrive - Aarhus universitet\AU-CIVIL1\2\ThermoSim\Grid.jl:32
 [2] top-level scope at none:0

Did they change something with scope again? Using Julia 1.1.1

Kind regards

Figured it out, I just had to write “global” infront of k in the for loop. Maybe there is a better way? My approach is not working so well right now, since I want “k” ie. my struct to hold x and y location for many nodes of different id’s - just can’t figure out how to achieve that

You can write local k in front of the loop.

1 Like

Thanks! That worked

You want to avoid global like the plague… Unless it is a very deliberate design decision, which is rarely necessary outside of packages

I am trying to generate a grid of nodes (ie. a grid of points) and I want each point to be described by the “MyStruct”, so that in the future I can access the values of this node using MyStruct (via the id field name) - I don’t know if this is the best approach but what I am doing currently is not working since MyStruct is only able to handle one point at a time… Any suggestions?

Kind regards

My suggestion is to avoid defining custom structures until you get a little more comfortable with the language. Unless you the structures for multiple dispatch, having it return matrices of the id,x,y (which you can collect in a named tuple if you wish to have them in one place) may be easier.

Using structs is pretty much the first thing you learn about the language after some basic syntax.

One suggestion would be to have an array of MyStruct so something like

struct MyStruct
    id::Int
     x::Float64
     y::Float64
end

function SquareGrid(nStart,nEnd,nStep)
    x  = collect(range(nStart,nEnd, step=nStep))
    nP = size(x)[1]
    return [MyStruct(i, x[i], x[i]) for i in 1:nP]
end

and then you get

julia> ks = SquareGrid(1, 10, 1)
10-element Array{MyStruct,1}:
 MyStruct(1, 1.0, 1.0)
 MyStruct(2, 2.0, 2.0)
 MyStruct(3, 3.0, 3.0)
 MyStruct(4, 4.0, 4.0)
 MyStruct(5, 5.0, 5.0)
 MyStruct(6, 6.0, 6.0)
 MyStruct(7, 7.0, 7.0)
 MyStruct(8, 8.0, 8.0)
 MyStruct(9, 9.0, 9.0)
 MyStruct(10, 10.0, 10.0)

julia> ks[3].id
3
4 Likes

Thanks exactly what I wanted, and thank you for showcasing how to access the individual elements. If someone wants to extract the whole array I discovered this notation:

ks.↦ :id

Taken from this answer https://stackoverflow.com/questions/46820304/best-way-to-access-field-in-array-of-structs-in-julia