在 Julia 中删除结构

Geo*_*ery 11 julia

我创建了一个复合类型

mutable struct Person
    id::Int64
end
Run Code Online (Sandbox Code Playgroud)

这很顺利,所以我想像这样扩展类型

mutable struct Person
    id::Int64
    contacts::Array{Int64}
end
Run Code Online (Sandbox Code Playgroud)

但有人告诉我这是一个invalid redefinition of constant Person.

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

ffe*_*tte 25

不幸的是,这是 的少数限制之一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
Run Code Online (Sandbox Code Playgroud)




在新类型的开发阶段,我有时会使用以下技巧。不过,这有点像黑客,我不确定我是否应该建议它:使用风险自负。

这个想法在于编号您的实际类型定义,命名你喜欢的类型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
Run Code Online (Sandbox Code Playgroud)

现在假设您要更改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
Run Code Online (Sandbox Code Playgroud)

  • 我真的很喜欢你的回答。它回答了问题,解释了背景并提供了一个非常好的解决方法。多谢。 (5认同)

fre*_*kre 5

不,如果不重新启动 Julia,这是不可能的。

  • 我想“如果不重新启动 Julia,这是不可能的。” (4认同)