Julia中的字段和属性之间有什么区别? [英] What is the difference between fields and properties in Julia?

查看:68
本文介绍了Julia中的字段和属性之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 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中的字段和属性之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆