Xóa cấu trúc trong Julia


8

Tôi đã tạo một kiểu hỗn hợp

mutable struct Person
    id::Int64
end

Điều này đã ổn, vì vậy tôi muốn mở rộng loại như thế này

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

nhưng tôi nói rằng đây là một invalid redefinition of constant Person.

Làm cách nào để xóa một loại? Có cách nào khác ngoài việc khởi động lại REPL không? (Làm ơn nói có đi.)


Bạn đã thử sử dụng Revise?
Oscar Smith

Revise không xử lý các định nghĩa lại cấu trúc, xem timholy.github.io/Revise.jl/urdy/limemony .
fredrikekre

Câu trả lời:


17

Thật không may, đây là một trong số ít những hạn chế của Revise.jl(và nếu có một cách để làm điều đó, nó có thể sẽ được thực hiện trong Revise). Vì vậy, ngay cả khi sử dụng Revisebạn hiện phải khởi động lại julia để thay đổi định nghĩa của một loại.

Hãy để tôi chỉ cố gắng minh họa lý do tại sao điều này hiện không thể:

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




Đôi khi tôi sử dụng thủ thuật sau trong giai đoạn phát triển của một loại mới. Tuy nhiên, đây là một phần của hack và tôi không chắc mình nên khuyên nó: hãy tự chịu rủi ro khi sử dụng.

Ý tưởng bao gồm đánh số các định nghĩa loại thực tế của bạn, đặt tên các loại của bạn như Person1,Person2 với số phiên bản được tăng lên mỗi khi định nghĩa thay đổi. Để sử dụng các tên loại được đánh số này nằm rải rác trên mã của bạn trong các định nghĩa phương thức, bạn có thể tạm thời đặt bí danh định nghĩa mới nhất cho một tên không bị lẫn lộn thông thường.

Ví dụ, giả sử bạn có triển khai Personloại đầu tiên , chỉ có một tên:

# 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

Bây giờ giả sử bạn muốn thay đổi định nghĩa của Personloại để thêm một idtrường:

# 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

2
Tôi thực sự thích câu trả lời của bạn. Nó trả lời câu hỏi, giải thích nền và cung cấp một cách giải quyết thực sự tốt. Cảm ơn rất nhiều.
Georgery

5

Không, điều này là không thể nếu không khởi động lại Julia.


Xin lỗi, câu này được cho là gì?
Georgery

2
Tôi đoán "điều này là không thể nếu không khởi động lại Julia."
DNF

Xin lỗi, làm hỏng chỉnh sửa của tôi. Đã sửa, cảm ơn.
fredrikekre
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.