ruby中的产量问题

ruby中的产量问题,ruby,yield,Ruby,Yield,我运行一个简单的函数: def test a = 10 yield a puts a end test { |x| x += 10 } def test(x) x += 10 end 得到一个意想不到的答案 > 10 接下来,我尝试以这种方式重用该函数: def test a = 10 a = yield a puts a end 结果是 > 20 但是我发现这段代码很难看,不是ruby风格的,我如何改进它呢?假设您有这个函数

我运行一个简单的函数:

def test 
   a = 10
   yield a
   puts a
end

test { |x| x += 10 }
def test(x)
  x += 10
end
得到一个意想不到的答案

> 10
接下来,我尝试以这种方式重用该函数:

def test 
   a = 10
   a = yield a
   puts a
end
结果是

 > 20

但是我发现这段代码很难看,不是ruby风格的,我如何改进它呢?

假设您有这个函数:

def test 
   a = 10
   yield a
   puts a
end

test { |x| x += 10 }
def test(x)
  x += 10
end
如果我有:

a = 10
test(a)
a
不会更改。因此,在您的示例中,
a
在执行块后仍然是10

如果有的话,你可以做:

def test 
   puts yield 10
end

假设你有这个功能:

def test 
   a = 10
   yield a
   puts a
end

test { |x| x += 10 }
def test(x)
  x += 10
end
如果我有:

a = 10
test(a)
a
不会更改。因此,在您的示例中,
a
在执行块后仍然是10

如果有的话,你可以做:

def test 
   puts yield 10
end
理论: 在ruby中,一切都是引用。这是什么意思?您使用的每一位数据(如数字10或字符串“hello world”)都是在内存中的某个位置创建的。所有变量(也放在内存中)都指向对象所占用的内存位置

有两种类型的对象-可变和不可变。可变对象可以被修改,也就是说,如果我们在内存中放置了一个字符串“hello”,我们可以修改它而不改变它在内存中的位置,因此指向它的位置的所有其他变量也会产生更改的值。例如:

a = b = 'hello'
a[2] = 'b'

a   #=> 'heblo'
b   #=> 'heblo'
所以您已经在内存中创建了“hello”字符串对象,并将变量a和b指向其内存位置。现在如果修改它,因为两个变量都指向同一个位置,所以两个变量似乎都改变了。然而,对新价值的认同

a = 'foo'
b #=> 'heblo'
没有修改对象。而是在内存中创建一个新对象,并将变量b指向该对象的内存位置。还请注意:

a = 'foo'
b = 'foo'
将在内存中创建两个单独的对象,变量a和b指向不同的位置

不可变对象不能修改,也不能复制。这意味着在内存中始终最多有一个表示给定对象的位置。例如,所有fixnum都是不可变的(还有nil、false、true和symbols)。因此,该代码:

a = 1
b = 1
将使两个变量都指向内存中的同一位置。这其实并不重要,因为存储在那个里的对象无论如何都不能被修改

您的问题: 那么,当您将一个变量生成一个块时会发生什么呢。新变量被创建为指向内存中的相同位置。因为您正在生成一个fixnum,而该fixnum是不可变的,所以不能修改它。因此,`x+=10'实际上将新的局部变量x重新指向内存中的不同位置,因此原始的x没有改变

如果传递一个字符串并对其进行修改,则看起来会有所不同:

def test
  a = 'foo'
  yield a
  puts a
end

test { a.replace 'bar' }

# Output: 'bar'
请注意
replace
方法,该方法修改字符串而不重新启动内存指针。

理论: 在ruby中,一切都是引用。这是什么意思?您使用的每一位数据(如数字10或字符串“hello world”)都是在内存中的某个位置创建的。所有变量(也放在内存中)都指向对象所占用的内存位置

有两种类型的对象-可变和不可变。可变对象可以被修改,也就是说,如果我们在内存中放置了一个字符串“hello”,我们可以修改它而不改变它在内存中的位置,因此指向它的位置的所有其他变量也会产生更改的值。例如:

a = b = 'hello'
a[2] = 'b'

a   #=> 'heblo'
b   #=> 'heblo'
所以您已经在内存中创建了“hello”字符串对象,并将变量a和b指向其内存位置。现在如果修改它,因为两个变量都指向同一个位置,所以两个变量似乎都改变了。然而,对新价值的认同

a = 'foo'
b #=> 'heblo'
没有修改对象。而是在内存中创建一个新对象,并将变量b指向该对象的内存位置。还请注意:

a = 'foo'
b = 'foo'
将在内存中创建两个单独的对象,变量a和b指向不同的位置

不可变对象不能修改,也不能复制。这意味着在内存中始终最多有一个表示给定对象的位置。例如,所有fixnum都是不可变的(还有nil、false、true和symbols)。因此,该代码:

a = 1
b = 1
将使两个变量都指向内存中的同一位置。这其实并不重要,因为存储在那个里的对象无论如何都不能被修改

您的问题: 那么,当您将一个变量生成一个块时会发生什么呢。新变量被创建为指向内存中的相同位置。因为您正在生成一个fixnum,而该fixnum是不可变的,所以不能修改它。因此,`x+=10'实际上将新的局部变量x重新指向内存中的不同位置,因此原始的x没有改变

如果传递一个字符串并对其进行修改,则看起来会有所不同:

def test
  a = 'foo'
  yield a
  puts a
end

test { a.replace 'bar' }

# Output: 'bar'

请注意
replace
方法,该方法修改字符串而无需重新启动内存指针。

Ruby与几乎所有现代语言一样,是按值传递的。您不能从调用者的作用域中改变变量绑定。

Ruby与几乎所有现代语言一样,是按值传递的。不能从调用方的作用域中变异变量绑定。

通过
test{x | x+=10}
def test;a=10;产生a;提出了一个解决方案;结束
评估为
def测试;a=10;20; 提出了一个解决方案;结束
。您可以看到,
a
不会因此而改变。是的,红宝石有时在外观上有点家常,但仍然很漂亮。您的第二次尝试是非常“Ruby风格”。我唯一要更改的是块本身:
{x | x+10}
通过
test{x | x+=10}
def test;a=10;产生a;提出了一个解决方案;结束
评估为
def测试;a=10;20; 提出了一个解决方案;结束
。您可以看到,
a
不会因此而改变。是的,红宝石有时在外观上有点家常,但仍然很漂亮。您的第二次尝试是非常“Ruby风格”。我唯一要更改的是块本身:
{x | x+10}