问题描述
Julia 有 setter 函数 setproperty!
和 setfield!
以及 getter 函数 getproperty
和 getfield
在结构上.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)
推荐答案
fields
只是结构的组件".结构体
fields
are simply the "components" of a struct. The struct
struct A
b
c::Int
end
具有字段 b
和 c
.调用 getfield
返回绑定到字段的对象:
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"
在 Julia 的早期版本中,语法 a.b
用于降低",即与编写 getfield(a, :b)
相同.现在改变的是 a.b
降低为 getproperty(a, :b)
并具有默认的回退
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)
所以默认情况下,什么都没有改变.但是,结构的作者可以重载 getproperty
(不可能重载 getfield
)来为点语法提供额外的功能:
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"
所以我们可以为点语法添加额外的功能(如果我们愿意,可以动态添加).作为一个有用的具体示例是包 PyCall.jl,您过去必须在其中编写 pyobject[:field]
而现在可以实现它以便您可以编写 pyobject.field.
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.
setfield!
和 setproperty!
之间的区别类似于 getfield
和 getproperty
之间的区别,解释以上.
The difference between setfield!
and setproperty!
is analogous to the difference between getfield
and getproperty
, explained above.
此外,可以挂钩到函数 Base.propertynames
以在 REPL 中提供属性的制表符补全.默认情况下,只会显示字段名称:
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
但是通过重载 propertynames
我们可以让它也显示额外的属性 q
:
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
这篇关于Julia 中的字段和属性有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!