gpt4 book ai didi

ruby - 无需 Marshal 帮助创建对象深拷贝的方法

转载 作者:数据小太阳 更新时间:2023-10-29 07:54:56 24 4
gpt4 key购买 nike

我有 3 个简单的类 CashRegister、Bill 和 Position。 CashRegister 由 Bill 对象组成,Bill 对象由 Position 对象组成。它们的实现方式如下

class CashRegister
def initialize
@bills = []
end

def clone
#?
end
end

class Bill
def initialize(nr)
@nr = nr
@positions = []
end

def clone
#?
end
end

class Position
def initialize(product, price)
@product = product
@price = price
end

def clone
#?
end
end

如何创建可以深度复制这些类对象的方法。不允许使用 Marshal.load(Marshal.dump(an_obj))

编辑:到目前为止我得到了这个:

    class CashRegister
def initialize
@bills = []
end

def clone
@bills.map { |bill| bill.clone}
end
end

class Bill
def initialize(nr)
@nr = nr
@positions = []
end

def clone
cloned = super
cloned.positions = @positions.map{ |pos| pos.clone}
cloned
end
end

class Position

attr_reader :preis
# this method is given
def produkt
@produkt.clone()
end

def initialize(product, price)
@product = product
@price = price
end

def clone
cloned = super
cloned.product
cloned
end
end

类 Position 中的克隆方法似乎没问题(没有编译错误)。但是在类 Bill 中有一个错误,它说“未定义的方法‘positions=’,所以问题一定在 cloned.positions = @positions.map{ |pos| pos.clone} 行中。但是我不明白,我们不能这样调用 cloned.positions 吗?

最佳答案

这只是您需要担心的实例变量。

class Position
attr_accessor :product, :price
def initialize(product, price)
@product = product
@price = price
end
end

p1 = Position.new("lima beans", 2.31)
#=> #<Position:0x000000027587b0 @product="lima beans", @price=2.31>
p2 = Position.new(p1.product, p1.price)
#=> #<Position:0x0000000273dd48 @product="lima beans", @price=2.31>

我们可以确认p2p1的深拷贝。

p1.product = "lettuce"
p1.price = 1.49

p1 #=> #<Position:0x0000000271f870 @product="lettuce", @price=1.49>
p2 #=> #<Position:0x000000026e9e00 @product="lima beans", @price=2.31>

p2.product = "spinach"
p2.price = 2.10

p1 #=> #<Position:0x0000000271f870 @product="lettuce", @price=1.49>
p2 #=> #<Position:0x000000026e9e00 @product="spinach", @price=2.1>

例如,如果类定义如下(其中 products 是一个数组),情况会更加复杂。

p1 = Position.new ["carrots", "onions"]
#=> #<Position:0x000000025b8928 @products=["carrots", "onions"]>
p2 = Position.new p1.products
#=> #<Position:0x000000025b0048 @products=["carrots", "onions"]>

p1.products << "beets"

p1 #=> #<Position:0x000000025b8928 @products=["carrots", "onions", "beets"]>
p2 #=> #<Position:0x000000025b0048 @products=["carrots", "onions", "beets"]>

p2 不是我们想要的。我们需要写

p1 = Position.new ["carrots", "onions"]
#=> #<Position:0x00000002450900 @products=["carrots", "onions"]>
p2 = Position.new p1.products.dup
#=> #<Position:0x0000000243aa88 @products=["carrots", "onions"]>

(注意 .dup)这样

p1.products << "beets"
#=> ["carrots", "onions", "beets"]

p1 #=> #<Position:0x00000002450900 @products=["carrots", "onions", "beets"]>
p2 #=> #<Position:0x0000000243aa88 @products=["carrots", "onions"]>

更一般地说,我们需要对实例变量进行深拷贝。

关于ruby - 无需 Marshal 帮助创建对象深拷贝的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44989348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com