我在stackoverflow和Julia文档中都找不到以下“设计问题”的答案:

假设我要定义以下对象

struct Person
birthplace::String
age::Int
end


由于Person是不可变的,我很高兴没有人可以更改所创建的任何birthplacePerson,但这也意味着,随着时间的流逝,我也不能更改其age

另一方面,如果我将类型Person定义为

mutable struct Person
birthplace::String
age::Int
end


我现在可以将它们设置为age,但是我没有以前在birthplace上拥有的安全性,任何人都可以访问它并进行更改。

我到目前为止发现的解决方法如下

struct Person
birthplace::String
age::Vector{Int}
end


其中age显然是1元素Vector
我发现此解决方案非常难看,而且绝对不是最佳选择,因为每次都必须使用方括号来访问年龄。

还有其他更优雅的方式在对象中同时具有不变字段和可变字段吗?

也许问题是我错过了struct中所有可变或不可变的真实价值。如果是这样,您能解释一下吗?

最佳答案

对于此特定示例,似乎应该存储生日而不是年龄,因为生日也是不可变的,并且根据该信息计算年龄很简单,但这也许只是一个玩具示例。




我发现这种解决方案非常丑陋,而且绝对不够理想
每次使用方括号访问年龄。


通常,您会定义一个吸气剂,即使用age(p::Person) = p.age[1]之类的东西,而不是直接访问该字段。这样可以避免括号中的“丑陋”。

在这种情况下,我们只想存储一个值,也可以使用Ref(或者可能是0维Array),例如:

struct Person
    birthplace::String
    age::Base.RefValue{Int}
end
Person(b::String, age::Int) = Person(b, Ref(age))
age(p::Person) = p.age[]


用法:

julia> p = Person("earth", 20)
Person("earth", 20)

julia> age(p)
20

关于struct - Julia结构中的可变字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48401315/

10-16 23:30