关于fieldnames和propertynames的一个小发现

笔者在学习:《Julia 语言程序设计》时,关于“参数化抽象类型”有如下各程序:

abstract type Pointy{T} end
mutable struct Point1D{T} <: Pointy{T}
           x :: T
        end
mutable struct Point2D{T} <: Pointy{T}
          x :: T
          y :: T
        end
mutable struct Point3D{T} <: Pointy{T}
         x :: T
         y :: T
         z :: T
        end
function modulett(p :: Pointy)
           m = 0
           for fieldss in fieldnames(p)
               m += getfield(p,fieldss)^2
           end
           sqrt(m)
        end
p1 = Point1D{Int64}(1)
p2 = Point2D{Int64}(2, 2)
p3 = Point3D(1+2*im, 3+4*im, 5-6*im)
mp1 = modulett(p1)
mp2 = modulett(p2)
mp3 = modulett(p3)

会出现如下错误:
ERROR: MethodError: no method matching fieldnames(::Point1D{Int64})
我发现:对于具体变量不能使用fieldnames(x)取得字段名,如:

julia> x = 3 // 5;

julia> fieldnames(x)

所以针对以上情况有两种方案来解决:

  1. typeof()函数来得到字段名
julia> fieldnames(typeof(x))
(:num, :den)
  1. 利用’propertynames()`来得到变量的字段名
julia> propertynames(x)
(:num, :den)
  1. 而对于相应的函数getfield()getproperty()则没有上述的限制:
julia> x = 3 // 5;

julia> getfield(x,:num)
3

julia> getproperty(x,:num)
3

当然如果为养成良好的编程习惯,两者前后对应使用才是最好的选择。

1 个赞