Consider the following code:
struct Employee
ID::Int32
name::String
end
and I can create an object and call any field:
svetlana = Employee(1,"Queen Svetlana")
println(svetlana.name)
If I require validation, I can have an inner constructor:
struct Employee
ID::Int32
name::String
function Employee(ID::Int32,name::String)
if ID < 0
error("ID is invalid!")
end
if isempty(name)
error("Employee name cannot be blank!")
end
ID = ID
name = name
new(ID,name)
end
end
When I remove the variable assignment in the constructor, how do the fields get assigned? I can still call ID
or name
and get the value:
struct Employee
ID::Int32
name::String
function Employee(ID::Int32,name::String)
if ID < 0
error("ID is invalid!")
end
if isempty(name)
error("Employee name cannot be blank!")
end
new(ID,name)
end
end
The ID
and name
in this case are the ones I passed into the constructor, and once they’re validated I return them.
svetlana = Employee(1,"Queen Svetlana")
println(svetlana.name)
Why does calling svetlana.name
and get the value?
1 Like
Not sure I understand the question fully, but the ID
and name
fields do not get set on the struct by the assignments, but by the new(ID, name)
call whose result (an Employee
) you subsequently return from the constructor. Hence, the assignments are not useful (certainly not in the form ID=ID
as you used).
2 Likes
In the internal constructor method, ID
and name
are just parameters.
The special function new()
creates an object with these parameters, therefore, they do not necessarily have to have the same name as the structure’s attributes. Ex:
struct Employee
ID::Int32
name::String
function Employee(id::Int32, n::String)
if id < 0
error("ID is invalid!")
end
if isempty(n)
error("Employee name cannot be blank!")
end
new(id, n)
end
end
PS: Sorry for my english.
3 Likes
To complement the other answers, the fields are filled in the order they are defined in the struct, by the arguments to new
. Since ID
is the first field in the struct it gets the value from the first argument to new
, and so on.
4 Likes
In the documentation, the inner constructor does have assignments (it does some calculations before it does the assignment).
To clarify, when I remove the assignments, how does ID
and name
still get its values assigned? I always assumed constructors were supposed to assign the values.
In the example you refer to the values of num
and den
are recalculated, based on the value of g
. That is why those assignments are there. But the values are set on the struct by the new(num, den)
call.
No, it really is the new()
call that assigns the values. You might be familiar with C++ for setting fields in constructors, but in Julia it works differently. You could just as easily have used new(3, 4)
to set the num
and den
values of the struct. In fact, the return value of the constructor is actually what is used:
julia> struct Employee
ID::Int32
name::String
function Employee(ID::Int, name::String)
return 1.23
end
end
julia> e = Employee(9, "abc")
1.23
julia> typeof(e)
Float64
2 Likes
If I wanted to do some work on the string, like strip it to remove white space and call title()
, then would the assignments make sense?
function Employee(ID::Int32, name::String)
if isempty(strip(name))
error("Employee name cannot be blank!")
end
name = title(name)
new(ID,name)
end
You could either assign the updated value to name
and then pass that to new()
or call new(ID, title(name))
directly, it has the same end result.
2 Likes