JKRT
JKRT

Reputation: 1207

Are static variables possible in mutable Julia structs?

I would like to able to define a static variable inside a Julia struct. E.g I would like to define something along the lines of:

mutable struct MyStruct
  global const a = 1
  b = 2
end

Then I would like to be able to access a, in a similar fashion to static constants in the Java or C++ languages, e.g:

MyStruct.a

I am very well aware that this way of writing code is not-Julian, and that I just could use a module for this purpose.

However, I am interested in whether it is possible or not for mutable structs. E.g I am interested in in details why this is not possible and techniques to emulate this pattern of programming.

Upvotes: 4

Views: 1007

Answers (3)

Bill
Bill

Reputation: 6086

(edit since you asked for something that does not require an instance of the struct)

Another way to do this is:

julia> mutable struct MyStruct b::Int end

julia> a(::Type{MyStruct}) = 1
a (generic function with 1 method)

julia> a(MyStruct)
1

which is accessed as a(Mystruct) instead of MyStruct.a

============================================================ (first answer):

You will need one more struct, and the syntax would be x.a.a not x.a:

julia> struct A
   a::Int
   end

julia> A() = A(1)
A

julia> s = A()
A(1)

julia> s.a
1

julia> mutable struct MyStruct
   a::A
   b::Int
   end

julia> MyStruct(b) = MyStruct(A(), b)
MyStruct

julia> c = MyStruct(3)
MyStruct(A(1), 3)

julia> c.a.a
1

julia> c.a.a = 5
ERROR: type A is immutable

Upvotes: 3

Oscar Smith
Oscar Smith

Reputation: 6378

I think the answer you are actually looking for is a const variable outside of a struct. The reason static variables exist in OOP languages is that sometimes you want a variable that isn't connected to an instance of a class. In Julia, you can do that just by using a variable.

const a = 1
mutable struct Mystruct
    b::Int
end

will provide the functionality you want. It won't look object oriented, because that isn't how Julia is designed.

Upvotes: 0

DNF
DNF

Reputation: 12654

Not sure exactly what you want, but

mutable struct MyStruct end

Base.getproperty(s::MyStruct, sym::Symbol) = (sym==:a ? 1 : getfield(s, sym))

julia> m = MyStruct()

julia> m.a
1

julia> m.a = 2
ERROR: type MyStruct has no field a
Stacktrace:
 [1] setproperty!(::MyStruct, ::Symbol, ::Int64) at ./Base.jl:21
 [2] top-level scope at REPL[18]:1

Or you can type MyStruct().a

You could also overload setproperty! to provide a more informative error message.

Upvotes: 1

Related Questions