Julia의 필드와 속성의 차이점은 무엇입니까?


23

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)

답변:


27

fields단순히 구조체의 "구성 요소"입니다. 구조체

struct A
   b
   c::Int
end

필드를 가지고 bc. getfield필드에 바인딩 된 객체 를 반환 하는 호출 :

julia> a = A("foo", 3)
A("foo", 3)

julia> getfield(a, :b)
"foo"

Julia의 초기 버전에서 구문 a.b은 "낮게"(즉, writing과 동일) 사용되었습니다 getfield(a, :b). 이제 변경된 것은 기본 폴백으로 a.b낮아집니다.getproperty(a, :b)

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

따라서 기본적으로 아무것도 변경되지 않았습니다. 그러나 구조체의 작성자 는 도트 구문에 추가 기능을 제공하기 위해 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"

따라서 도트 구문에 추가 기능을 추가 할 수 있습니다 (원하는 경우 동적으로). 이것이 유용한 구체적인 예로 PyCall.jl 패키지가 있는데, 여기서는 작성해야 pyobject[:field] 했지만 이제는 작성할 수 있도록 구현할 수 있습니다.pyobject.field.

차이 setfield!setproperty!의 차이와 유사 getfield하고 getproperty, 상기 설명했다.

또한 Base.propertynamesREPL에서 속성의 탭 완성을 제공하기 위해 함수에 연결할 수 있습니다. 기본적으로 필드 이름 만 표시됩니다.

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

그러나 과부하로 propertynames인해 추가 속성을 표시 할 수도 있습니다 q.

julia> Base.propertynames(::A) = (:b, :c, :q)

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

getfield를 오버로드 할 수 없습니까?
Alfaizkhan 2009 년

3
아니요, getfield특수 (내장) 기능입니다. 과부하를 시도하면 오류가 발생 cannot add methods to a builtin function합니다.
Kristoffer Carlsson

어쩌면 그 정보를 어딘가에 대답에 추가 할 수 있습니까?
StefanKarpinski 19

2
대답은 이미 명시 적으로 "(오버로드 할 수 없음 getfield)"이라고 표시되어 있으므로 어떤 의미에서는 이미 있습니다.
Kristoffer Carlsson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.