Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
令人困惑的Ruby方法返回值_Ruby_Methods_Return Value - Fatal编程技术网

令人困惑的Ruby方法返回值

令人困惑的Ruby方法返回值,ruby,methods,return-value,Ruby,Methods,Return Value,我有Ruby代码: def test_111(hash) n = nil 3.times do |c| if n n[c] = c else n = hash end end end a = {} test_111(a) p a 为什么它打印{1=>1,2=>2},而不是{} 在test_111方法中,散列和a使用相同的内存 在test_111方法中,如何更改a值 我不明白散列是通过引用传递的。因此,当您更改作为散列

我有Ruby代码:

def test_111(hash)
  n = nil
  3.times do |c|
      if n
       n[c] = c
      else
       n = hash
      end
  end
end

a = {}
test_111(a)
p a
为什么它打印{1=>1,2=>2},而不是{}

在test_111方法中,散列和a使用相同的内存

在test_111方法中,如何更改a值


我不明白散列是通过引用传递的。因此,当您更改作为散列的方法参数时,您将更改原始散列

为了避免这种情况,您应该克隆散列

test_111(a.dup)
这将创建一个浅拷贝,也就是说,它不会克隆您可能拥有的子哈希

关于浅拷贝是什么的一个小说明:

def mutate hash
  hash[:new] = 1
  hash[:existing][:value] = 2
  hash
end

h = {existing: {value: 1}}

mutate h # => {:existing=>{:value=>2}, :new=>1}
# new member added, existing member changed
h # => {:existing=>{:value=>2}, :new=>1}



h = {existing: {value: 1}}

mutate h.dup # => {:existing=>{:value=>2}, :new=>1}
# existing member changed, no new members
h # => {:existing=>{:value=>2}}

散列是通过引用传递的。因此,当您更改作为散列的方法参数时,您将更改原始散列

为了避免这种情况,您应该克隆散列

test_111(a.dup)
这将创建一个浅拷贝,也就是说,它不会克隆您可能拥有的子哈希

关于浅拷贝是什么的一个小说明:

def mutate hash
  hash[:new] = 1
  hash[:existing][:value] = 2
  hash
end

h = {existing: {value: 1}}

mutate h # => {:existing=>{:value=>2}, :new=>1}
# new member added, existing member changed
h # => {:existing=>{:value=>2}, :new=>1}



h = {existing: {value: 1}}

mutate h.dup # => {:existing=>{:value=>2}, :new=>1}
# existing member changed, no new members
h # => {:existing=>{:value=>2}}

在ruby中,几乎每个对象都是通过引用传递的。这意味着当你做一些简单的事情

a = b
除非a是简单类型之一,否则在赋值之后,a和b将指向同一个对象

这意味着,如果更改第二个变量,第一个变量将受到相同的影响:

irb(main):001:0> x = "a string"
=> "a string"
irb(main):002:0> y = x
=> "a string"
irb(main):003:0> x[1,0] = "nother"
=> "nother"
irb(main):004:0> x
=> "another string"
irb(main):005:0> y
=> "another string"
irb(main):006:0> 
当然,这同样适用于散列:

irb(main):006:0> a = { :a => 1 }
=> {:a=>1}
irb(main):007:0> b = a
=> {:a=>1}
irb(main):008:0> a[:b] = 2
=> 2
irb(main):009:0> a
=> {:a=>1, :b=>2}
irb(main):010:0> b
=> {:a=>1, :b=>2}
irb(main):011:0> 
如果不希望发生这种情况,请使用.dup或.clone:

对大多数人来说,复制和克隆具有相同的效果

因此,如果您编写的函数修改了其中一个参数,除非您特别希望调用该函数的代码能够看到这些更改,否则您应该首先复制要修改的参数:

def test_111(hash)
  hash = hash.dup
  # etc
end

代码的行为称为副作用,即对程序状态的更改,它不是函数的核心部分。通常要避免副作用。

在ruby中,几乎每个对象都是通过引用传递的。这意味着当你做一些简单的事情

a = b
除非a是简单类型之一,否则在赋值之后,a和b将指向同一个对象

这意味着,如果更改第二个变量,第一个变量将受到相同的影响:

irb(main):001:0> x = "a string"
=> "a string"
irb(main):002:0> y = x
=> "a string"
irb(main):003:0> x[1,0] = "nother"
=> "nother"
irb(main):004:0> x
=> "another string"
irb(main):005:0> y
=> "another string"
irb(main):006:0> 
当然,这同样适用于散列:

irb(main):006:0> a = { :a => 1 }
=> {:a=>1}
irb(main):007:0> b = a
=> {:a=>1}
irb(main):008:0> a[:b] = 2
=> 2
irb(main):009:0> a
=> {:a=>1, :b=>2}
irb(main):010:0> b
=> {:a=>1, :b=>2}
irb(main):011:0> 
如果不希望发生这种情况,请使用.dup或.clone:

对大多数人来说,复制和克隆具有相同的效果

因此,如果您编写的函数修改了其中一个参数,除非您特别希望调用该函数的代码能够看到这些更改,否则您应该首先复制要修改的参数:

def test_111(hash)
  hash = hash.dup
  # etc
end

代码的行为称为副作用,即对程序状态的更改,它不是函数的核心部分。副作用通常是要避免的。

Jörg W Mittag认为Ruby是无价值的。他还承认传递的值可以是指针。从一个糟糕的程序员的角度来看,这就是参考:Jörg W Mittag认为Ruby是通过值传递的。他还承认传递的值可以是指针。从一个糟糕的程序员的角度来看,这是一个参考: