Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between fields and properties in Julia?

Tags:

julia

Julia has the setter functions setproperty! and setfield! and the getter functions getproperty and getfield that operate on structs. What is the difference between properties and fields in Julia?

For example, the following seems to indicate that they do the same thing:

julia> mutable struct S            a        end  julia> s = S(2) S(2)  julia> getfield(s, :a) 2  julia> getproperty(s, :a) 2  julia> setfield!(s, :a, 3) 3  julia> s S(3)  julia> setproperty!(s, :a, 4) 4  julia> s S(4) 
like image 760
Kristoffer Carlsson Avatar asked Oct 01 '19 08:10

Kristoffer Carlsson


Video Answer


1 Answers

fields are simply the "components" of a struct. The struct

struct A    b    c::Int end 

has the fields b and c. A call to getfield returns the object that is bound to the field:

julia> a = A("foo", 3) A("foo", 3)  julia> getfield(a, :b) "foo" 

In early versions of Julia, the syntax a.b used to "lower", i.e. be the same as, writing getfield(a, :b). What has changed now is that a.b lowers to getproperty(a, :b) with the default fallback

getproperty(a::Type, v::Symbol) = getfield(a, v) 

So by default, nothing has changed. However, authors of structs can overload getproperty (it is not possible to overload getfield) to provide extra functionality to the dot-syntax:

julia> function Base.getproperty(a::A, v::Symbol)            if v == :c                return getfield(a, :c) * 2            elseif v == :q                return "q"            else                return getfield(a, v)            end        end  julia> a.q "q"  julia> getfield(a, :q) ERROR: type A has no field q  julia> a.c 6  julia> getfield(a, :c) 3  julia> a.b "foo" 

So we can add extra functionality to the dot syntax (dynamically if we want). As a concrete example where this is useful is for the package PyCall.jl where you used to have to write pyobject[:field] while it is possible now to implement it such that you can write pyobject.field.

The difference between setfield! and setproperty! is analogous to the difference between getfield and getproperty, explained above.

In addition, it is possible to hook into the function Base.propertynames to provide tab completion of properties in the REPL. By default, only the field names will be shown:

julia> a.<TAB><TAB> b c 

But by overloading propertynames we can make it also show the extra property q:

julia> Base.propertynames(::A) = (:b, :c, :q)  julia> a.<TAB><TAB> b c q 
like image 179
Kristoffer Carlsson Avatar answered Sep 21 '22 06:09

Kristoffer Carlsson