在Julia中删除结构体

15

我创建了一个复合类型

mutable struct Person
    id::Int64
end

这次进行得很顺利,因此我想要扩展类型,如下所示

mutable struct Person
    id::Int64
    contacts::Array{Int64}
end

但我被告知这是一个Person常量的无效重新定义

如何删除类型?除了重新启动REPL之外还有其他方法吗?(请说“是”)


你尝试过使用 Revise 吗? - Oscar Smith
Revise无法处理结构体的重新定义,请参见https://timholy.github.io/Revise.jl/stable/limitations/。 - fredrikekre
2个回答

31

这不幸地是Revise.jl的少数限制之一(如果有方法可以实现,它可能已在Revise中实现)。因此,即使使用Revise,您目前仍需要重新启动julia才能更改类型的定义。

让我试着解释一下当前无法实现的原因:

julia> struct Person
           name :: String
       end

julia> alice = Person("Alice")
Person("Alice")

# Imagine you have some magic trick that makes this possible:
julia> struct Person
           id   :: Int
           name :: String
       end

julia> bob = Person(42, "Bob")
Person(42, "Bob")

# What should be the type of alice now?
julia> alice
Person("Alice") # Not consistent with the current definition of Person




在新类型的开发阶段,我有时会使用以下技巧。虽然这是一种hack方法,但我不确定是否应该建议使用:请自行承担风险。

这个技巧的想法是对实际类型定义进行编号,并命名为Person1Person2等,版本号每次更改时递增。为了在方法定义中随处使用这些带数字的类型名称,您可以将最新的定义暂时别名为一个常见的无数字名称。

例如,假设您有一个Person类型的第一次实现,只有一个名称:

# First version of the type
julia> struct Person1
           name :: String
       end

# Aliased to just "Person"
julia> Person = Person1
Person1

# Define methods and instances like usual, using the "Person" alias
julia> hello(p::Person) = println("Hello $(p.name)")
hello (generic function with 1 method)

julia> alice = Person("Alice")
Person1("Alice")

julia> hello(alice)
Hello Alice

现在假设你想要改变Person类型的定义,以添加一个id字段:

# Second version of the type: increment the number
# This is strictly a new, different type
julia> struct Person2
           id   :: Int
           name :: String
       end

# But you can alias "Person" to this new type
julia> Person = Person2
Person2

# It looks as though you update the definition of the same "hello" method...
julia> hello(p::Person) = println("Hello $(p.name), you have id: $(p.id)")
hello (generic function with 2 methods)

# ...when in reality you are defining a new method
julia> methods(hello)
# 2 methods for generic function "hello":
[1] hello(p::Person2) in Main at REPL[8]:1
[2] hello(p::Person1) in Main at REPL[3]:1

julia> bob = Person(42, "Bob")
Person2(42, "Bob")

julia> hello(bob)
Hello Bob, you have id: 42

# alice is still of type "Person1", and old methods still work
julia> hello(alice)
Hello Alice

6
我非常喜欢你的回答。它回答了问题,解释了背景,并提供了一个非常好的解决方案。非常感谢。 - Georgery

6

不,不重新启动Julia是不可能实现的。


抱歉,这句话想表达什么意思? - Georgery
11
我猜想,“不重新启动Julia是不可能实现这个的”。 - DNF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接