Julia具有setter函数setproperty!和setfield!getter函数getproperty,getfield并且在结构上运行。Julia中的属性和字段之间有什么区别?
例如,以下内容似乎表明它们执行相同的操作:
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)
Run Code Online (Sandbox Code Playgroud)
Kri*_*son 26
fields仅仅是结构的“组件”。结构
struct A
b
c::Int
end
Run Code Online (Sandbox Code Playgroud)
有字段b和c。调用会getfield返回绑定到该字段的对象:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
Run Code Online (Sandbox Code Playgroud)
在Julia的早期版本中,语法a.b用来“降低”,即与Writing相同getfield(a, :b)。现在发生的变化是 使用默认后备广告a.b降低到getproperty(a, :b)
getproperty(a::Type, v::Symbol) = getfield(a, v)
Run Code Online (Sandbox Code Playgroud)
因此,默认情况下,什么都没有改变。但是,结构的作者可以重载getproperty(不可能重载getfield)以为点语法提供额外的功能:
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"
Run Code Online (Sandbox Code Playgroud)
因此,我们可以为点语法添加额外的功能(如果需要,可以动态地添加)。举一个有用的具体示例是PyCall.jl包,您曾经必须编写该包,pyobject[:field] 而现在可以实现它以便您可以编写pyobject.field.
之间的差setfield!和setproperty!类似于之间的差getfield和getproperty,如上所述。
另外,可以挂钩该函数Base.propertynames以在REPL中提供属性的制表符补全。默认情况下,仅显示字段名称:
julia> a.<TAB><TAB>
b c
Run Code Online (Sandbox Code Playgroud)
但是通过重载,propertynames我们可以使它也显示额外的属性q:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
626 次 |
| 最近记录: |