fields
chỉ đơn giản là "thành phần" của một cấu trúc. Cấu trúc
struct A
b
c::Int
end
có các lĩnh vực b
và c
. Một cuộc gọi để getfield
trả về đối tượng được liên kết với trường:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
Trong các phiên bản đầu của Julia, cú pháp a.b
được sử dụng để "hạ thấp", nghĩa là giống như cách viết getfield(a, :b)
. Điều đã thay đổi bây giờ là a.b
giảm xuống getproperty(a, :b)
với dự phòng mặc định
getproperty(a::Type, v::Symbol) = getfield(a, v)
Vì vậy, theo mặc định, không có gì thay đổi. Tuy nhiên, các tác giả của cấu trúc có thể quá tải getproperty
(không thể quá tải getfield
) để cung cấp chức năng bổ sung cho cú pháp dấu chấm:
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"
Vì vậy, chúng tôi có thể thêm chức năng bổ sung cho cú pháp dấu chấm (động nếu chúng tôi muốn). Như một ví dụ cụ thể, nơi điều này hữu ích cho gói PyCall.jl nơi bạn đã từng phải viết pyobject[:field]
trong khi bây giờ có thể thực hiện nó để bạn có thể viếtpyobject.field.
Sự khác biệt giữa setfield!
và setproperty!
tương tự như sự khác biệt giữa getfield
và getproperty
, được giải thích ở trên.
Ngoài ra, có thể nối vào hàm Base.propertynames
để cung cấp tab hoàn thành các thuộc tính trong REPL. Theo mặc định, chỉ tên trường sẽ được hiển thị:
julia> a.<TAB><TAB>
b c
Nhưng bằng cách quá tải, propertynames
chúng ta có thể làm cho nó cũng hiển thị các thuộc tính bổ sung q
:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q