锁定老帖子 主题:ruby 函数到底是按值传递还是按引用
精华帖 (0) :: 良好帖 (1) :: 新手帖 (3) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-11-07
例子:
def pref1(agr)
ruby 函数到底是按值传递还是按引用???
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-11-08
ruby中没有什么值传递和引用传递的概念。在ruby中一切都是对象,而你向方法中传递的实质上是对象的引用( object-reference)。ruby中变量都是对象的引用。
先来看
def pref2(agr)
agr.downcase end a2 = 'PREF2' pref2(a2) puts "#{a2}" #输出 PREF2
为什么调用了pref2后 a2还是大写的“PREF2”,看一下downcase的源码就不难发现问题了。
看到str=rb_str_dup(str); 这句其实真相大白了,实际上dwoncase返回的是一个新的字符串,并不是你原来传进去的字符串对象的引用了。 所以经过了pref2方法后,a2的值并没有发生改变。
再来看
def pref1(agr)
agr.downcase! end a1 = 'HELLO' pref1(a1) puts "#{a1}" #输出 hello
为什么经过了pref1方法a1的值发生了变化。还是先来看看downcase!的源码
查看源码后发现传入的对象引用自始至终未被更改过,所以最终返回的还是a1的引用,所以a1对象的内容在dwoncase!方法中被改变了。
太晚了,明日继续后两个
|
|
返回顶楼 | |
发表时间:2011-11-08
@洛克刘
膜拜大牛~ |
|
返回顶楼 | |
发表时间:2011-11-08
洛克刘 写道
ruby中没有什么值传递和引用传递的概念。在ruby中一切都是对象,而你向方法中传递的实质上是对象的引用( object-reference)。ruby中变量都是对象的引用。
先来看
def pref2(agr)
agr.downcase end a2 = 'PREF2' pref2(a2) puts "#{a2}" #输出 PREF2
为什么调用了pref2后 a2还是大写的“PREF2”,看一下downcase的源码就不难发现问题了。
看到str=rb_str_dup(str); 这句其实真相大白了,实际上dwoncase返回的是一个新的字符串,并不是你原来传进去的字符串对象的引用了。 所以经过了pref2方法后,a2的值并没有发生改变。
再来看
def pref1(agr)
agr.downcase! end a1 = 'HELLO' pref1(a1) puts "#{a1}" #输出 hello
为什么经过了pref1方法a1的值发生了变化。还是先来看看downcase!的源码
查看源码后发现传入的对象引用自始至终未被更改过,所以最终返回的还是a1的引用,所以a1对象的内容在dwoncase!方法中被改变了。
太晚了,明日继续后两个
等待中。。。。。。
|
|
返回顶楼 | |
发表时间:2011-11-08
最后修改:2011-11-08
接下来继续看看
def pref3(a,b)
a,b = b,a end a,b = 1,2 pref3(a,b) puts a,b #输出 1,2
为什么明明在pref3中交换了a,b结果为什么没变呢?这个问题确实比较难懂。我们可以把你的例子转换为一个更好理解的例子
变为
def pref3(a)
a = 5 end a =1 pref3(a) puts a #输出 1 明明把a传进去了,并给它赋值为5,为什么还是1呢?我们很自然的可以想到是不是外面的a和方法中的a不是同一个东西。为了验证,我们进一步改造我们的方法 改造
def pref3(a)
a = 5 a.object_id end a =1 a.object_id #输出3 pref3(a) #输出11 puts a 我们发现两个a的object_id不同,他们不是一个对象,而是两个。 现在我们明白了问题的关键,方法中的本地变量a指向了对象5,而外部的a仍旧指向的是对象1.
至此整个过程我们可以理解为:
现在回头想想你的方法中传进去的a,b虽然交换了位置,但是对外部定义的a,b没有丝毫影响。因为他们根本保存的就是不同的对象的引用。
|
|
返回顶楼 | |
发表时间:2011-11-08
" 至此整个过程我们可以理解为:
有一个对象1,我们用a保存了他的引用。 然后我们将它的“引用的拷贝”传递给了方法pref3中的本地变量a,这时本地变量a保存了1对象的引用。 我们在pref3方法中创建了5对象,将其引用赋值给了本地变量a,这时a擦去了保存的1对象的引用,而改为保存5对象的引用 调用完pref3方法 ,其本地变量a随之消亡,对象5因为没有引用而随后被垃圾回收。 而外部的变量a自始至终保存着对象1的引用。 " 很清析~~~ 太好啦~~~ 3Q~~~ 恩,这貌似在python里也是一样的~~ 恩,这里还一个作用域的问题~ |
|
返回顶楼 | |
发表时间:2011-11-09
最后修改:2011-11-14
ruby里全部都是指针吗? 我是来学习的。
|
|
返回顶楼 | |
发表时间:2011-11-09
|
|
返回顶楼 | |
发表时间:2011-11-09
最后修改:2011-11-09
在ruby里面对象分两类,对于可以在32 bit(其实没有32bit)中存得下的值,例如Fixnum,nil,true/false等,变量里面是存值的。对于其他对象,变量里面存的是指向对象的“句柄”。
ruby函数调用传递的是“值” - 净值(对于第一类),或句柄。 |
|
返回顶楼 | |
发表时间:2011-11-09
最后修改:2011-11-09
Hooopo 写道
但对于基本类型是直接传递对象本身的。举个例子: 写道
“Fixnum objects have immediate value. This means that when they are assigned or passed as parameters, the actual object is passed, rather than a reference to that object. Assignment does not alias Fixnum objects. There is effectively only one Fixnum object instance for any given integer value, so, for example, you cannot add a singleton method to a Fixnum.“.
我觉得这篇文章能够结束这个话题了:http://www.khelll.com/blog/ruby/c-passes-by-reference-java-and-ruby-dont/
更有趣的讨论过程:http://www.khelll.com/blog/ruby/ruby-pass-by-value-or-by-reference/
|
|
返回顶楼 | |