I am not a very good Julia programmer (despite reading the doc numerous times).
For what I am trying to code at the moment, I am trying to create something close to a Python class.
I thought of using a mutable struct, but I realized that one cannot initialize a variable as one of it’s argument. Something like
mutable struct Test
a
b
c = 3
end
returns the error
ERROR: syntax: "c=3" inside type definition is reserved
Stacktrace:
[1] top-level scope at none:0
Ultimatively what I want to do would be something like a
Class Test
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
self.matrix = foo(shape(var1))
And I don’t know how to do this in Julia if not for declaring matrix as a const outside of the struct which would be unpracticle.
I have already read the doc on constructors and composite types so please do not just tell me to “read the doc again”.
mutable struct Test
a::Float64
b::String
c::Int
end
test_object = Test(1.0, "Test", 1)
You don’t have Classes in Julia. Instead you first define the data structure (struct, e.g. what kind of data your objects should hold) and what type of data the structure will hold. Afterwards you create instances of those “objects” with concrete values for the variables (could also be variables from somewhere else).
You can then access this data directly if you want to:
Ah I see you’ve changed your question a bit since I first read it.
Now I would personally just do the following things to do what you want:
create a struct and add a field in the struct that is able to hold the desired matrix, i.e. has the appropriate type (e.g. c::Array{Int64, 2} or whatever you need)
mutable struct Test
a::Int
b::Int
c::Array{Int, 2}
create an anonymous function that creates the desired matrix (e.g. foo(a, b) = [a b])
initialise the object = Test(1, 2, [0 0]) with an empty Array for c
update the array to reflect what you want it to be (e.g. object.c = foo(object.a, object.b))
However, there might be better ways to do it.
Edit: Instead of writing [0 0] you could also write zeros(Int, 1, 2). This would be the preferred way to do it once your matrices become a lot bigger.
That is actually how I wanted to do it, but it feels a bit sloppy and forces me to include an extra input variable unpon instanciation so I thought maybe there is a better way to do it. Thanks for your help.
Yes my fnger slipped and pressed enter before I could properlly finish writting my question that’s why !
No worries, it’s not as if you could have anticipated my eagerness to help. Normally it’s no problem to rewrite parts of your question before people find the time to answer.
If there’s a better way to do what you want to do, there will surely be somebody coming along to tell us how.
I tested in a copy I had lying around (1.0.5), and it works. Just note that the constructor becomes: t = Test(a=1, b=2) not t = Test(1, 2) (i.e., if you do not want to pass the fields with default value, you need to pass the other fields as named arguments, the positional constructor keeps existing and expecting three arguments).
It seems my issues are a bit deeper than that. I’m using the mp! from 1.3 now and, having heard “The State of Julia” will be moving to 1.5-dependent things as soon as it’s released.
So, my 1.0 days are behind me. I need the non-allocating array slices bad. Using those will clean up my code in a significant way. I’m also happy to hear about the Givens rotations.
function shape(x)
return 3*x
end
struct Test
a :: Int64
b :: Int64
c :: Int64
function Test(x, y)
return new(x, y, shape(x))
end
end
julia> Test(1, 2)
Test(1, 2, 3)