Arrays 如何创建与原始数组共享相同实例的Ruby数组切片?

Arrays 如何创建与原始数组共享相同实例的Ruby数组切片?,arrays,ruby,Arrays,Ruby,因此,如果切片被更改,原始数组也将更改 a = [1, 2, 3] b = a[1, 2] b[0] = 42 # due to COW, only b changes, a remains unchanged 预期结果:当运行b[0]=42时,a[1]也将更改为42 编辑:这有图书馆吗 例如: a = [1, 2, 3] b = ArraySlice.new(a, 1, 2) ... # changes in b will be reflected in a 另外,我对Ruby还不熟悉。我

因此,如果切片被更改,原始数组也将更改

a = [1, 2, 3]
b = a[1, 2]
b[0] = 42 # due to COW, only b changes, a remains unchanged
预期结果:当运行
b[0]=42
时,
a[1]
也将更改为42

编辑:这有图书馆吗

例如:

a = [1, 2, 3]
b = ArraySlice.new(a, 1, 2)
... # changes in b will be reflected in a

另外,我对Ruby还不熟悉。我想要的与Java的基本相同。有时这很有用,因为我们可以避免创建太多的新数组对象。

我认为这是不可能的。虽然a和b引用相同的对象,但引用本身是不同的。因此,更新一个引用不会更新另一个引用。如果改为更改基础对象,则它们会按预期操作

a = [{}, {}, {}]
b = a[1,2]

b[0][:copy?] = true

puts a.inspect
#[{}, {:copy?=>true}, {}]

[]
创建一个新数组。从:

返回用给定对象填充的新数组


由于它是一个副本,更改新阵列不会更改原始阵列。

在核心库或标准库中都没有类似的情况,我也不知道有任何第三方库。你必须自己动手,可能是这样:

class ArraySlice
  include Enumerable

  def initialize(ary=[], start=0, length=ary.size - start)
    self.ary, self.start, self.length = ary, start, length
  end

  def [](*args)
    return ArraySlice.new(ary, args.first + start, args.last) if args.size == 2
    return ArraySlice.new(ary, args.first.begin + start, if args.first.exclude_end? then args.first.end - args.first.begin - 1 else args.first.end - args.first.begin end) if args.first.is_a?(Range)
    ary[args.first + start]
  end

  def []=(*args, value)
    return ary[args.first + start, length] = value if args.size == 2
    return ary[Range.new(args.first.begin + start, args.first.end + start, args.first.exclude_end?)] = value if args.first.is_a?(Range)
    ary[args.first + start] = value
  end

  def each(&blk)
    ary[start, length].each(&blk)
  end

  # and so on …

  private

  attr_accessor :ary, :start, :length
end

a = [1, 2, 3]
b = ArraySlice.new(a, 1, 2)
b[0] = 42
a[1] # => 42
a=[“a”、“b”、“c”]
b=a[1,2]
b、 每个{str}str[“a”,“b!”,“c!”]

不适用于整数等不可变对象。

不要将句子从标题延续到正文中。标题和正文之间的重复是可以的。我看不出有任何理由结束这个问题。问题问得恰当且清楚。@sawa COW的意思是写时复制,我在这里找到它:
a = ["a", "b", "c"]
b = a[1, 2]
b.each{|str| str << "!"}

p a # => ["a", "b!", "c!"]