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}