如何让数组只在Ruby函数内本地操作而不泄露?

2026-04-11 14:291阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计602个文字,预计阅读时间需要3分钟。

如何让数组只在Ruby函数内本地操作而不泄露?

当我在运行Ruby代码时,我的数组为什么会被全局操作?我怎么才能在函数范围内操作数组?

rubya +=[[1,0],[1,1]]def hasRowsWithOnlyOnes(array) array.map { |row| return true if row.keep_if { |i| i !=1 } }end

当我运行下面的 ruby代码时,为什么我的数组被全局操作?我怎样才能在函数范围内操作数组?

a = [[1,0],[1,1]] def hasRowsWithOnlyOnes(array) array.map { |row| return true if row.keep_if{|i| i != 1 } == [] } false; end puts a.to_s puts hasRowsWithOnlyOnes(a) puts a.to_s

$ruby​​ test.rb输出:

[[1, 0], [1, 1]] true [[0], []]

我无法让它发挥作用.我甚至尝试过.select {true}并将其分配给一个新名称.范围如何在Ruby for Arrays中运行?
仅供参考,$ruby​​ -v:

ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux] 这不是范围问题,而是一个传递问题的论据

> Ruby中的所有变量都是对象的引用.
>将对象传递给方法时,会生成该对象引用的副本并将其传递给该对象.

这意味着方法中的变量数组和顶级变量a引用完全相同的数组.对数组所做的任何更改也将作为a的更改显示,因为两个变量都引用同一个对象.

您的方法通过调用Array#keep_if来修改数组.hold_if方法就地修改数组.

修复

如何让数组只在Ruby函数内本地操作而不泄露?

对此的最佳解决方法是使其方法不会修改传入的数组.这可以使用Enumerable#any?和Enumerable#all?方法非常巧妙地完成:

def has_a_row_with_only_ones(array) array.any? do |row| row.all? { |e| e == 1 } end end

此代码表示如果对于任何行,该行中的每个元素都是1,则该方法返回true.这些方法不会修改数组.更重要的是,他们清楚地传达了方法的意图.

糟糕的解决方法

如果您希望通过数组的副本将该方法作为传递给它,以便可以修改该数组而不在该方法外部看到该修改,那么您可以对该数组进行深层复制.如this answer所示,您可以定义此方法以进行深层复制:

def deep_copy(o) Marshal.load(Marshal.dump(o)) end

然后,在方法的顶部,进行深层复制:

def has_a_row_with_only_ones(array) array = deep_copy(array) # code that modifies array end

这应该避免,因为它很慢.

本文共计602个文字,预计阅读时间需要3分钟。

如何让数组只在Ruby函数内本地操作而不泄露?

当我在运行Ruby代码时,我的数组为什么会被全局操作?我怎么才能在函数范围内操作数组?

rubya +=[[1,0],[1,1]]def hasRowsWithOnlyOnes(array) array.map { |row| return true if row.keep_if { |i| i !=1 } }end

当我运行下面的 ruby代码时,为什么我的数组被全局操作?我怎样才能在函数范围内操作数组?

a = [[1,0],[1,1]] def hasRowsWithOnlyOnes(array) array.map { |row| return true if row.keep_if{|i| i != 1 } == [] } false; end puts a.to_s puts hasRowsWithOnlyOnes(a) puts a.to_s

$ruby​​ test.rb输出:

[[1, 0], [1, 1]] true [[0], []]

我无法让它发挥作用.我甚至尝试过.select {true}并将其分配给一个新名称.范围如何在Ruby for Arrays中运行?
仅供参考,$ruby​​ -v:

ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux] 这不是范围问题,而是一个传递问题的论据

> Ruby中的所有变量都是对象的引用.
>将对象传递给方法时,会生成该对象引用的副本并将其传递给该对象.

这意味着方法中的变量数组和顶级变量a引用完全相同的数组.对数组所做的任何更改也将作为a的更改显示,因为两个变量都引用同一个对象.

您的方法通过调用Array#keep_if来修改数组.hold_if方法就地修改数组.

修复

如何让数组只在Ruby函数内本地操作而不泄露?

对此的最佳解决方法是使其方法不会修改传入的数组.这可以使用Enumerable#any?和Enumerable#all?方法非常巧妙地完成:

def has_a_row_with_only_ones(array) array.any? do |row| row.all? { |e| e == 1 } end end

此代码表示如果对于任何行,该行中的每个元素都是1,则该方法返回true.这些方法不会修改数组.更重要的是,他们清楚地传达了方法的意图.

糟糕的解决方法

如果您希望通过数组的副本将该方法作为传递给它,以便可以修改该数组而不在该方法外部看到该修改,那么您可以对该数组进行深层复制.如this answer所示,您可以定义此方法以进行深层复制:

def deep_copy(o) Marshal.load(Marshal.dump(o)) end

然后,在方法的顶部,进行深层复制:

def has_a_row_with_only_ones(array) array = deep_copy(array) # code that modifies array end

这应该避免,因为它很慢.