总结:Ruby里是值传递还是引用传递
在ruby中一切都是对象,而你向方法中传递的实质上是对象的引用( object-reference)。ruby中变量都是对象的引用。
先来看
def pref2(agr)
agr.downcase
end a2 = 'PREF2'
pref2(a2)
puts "#{a2}" #输出 PREF2
为什么调用了pref2后 a2还是大写的“PREF2”,看一下downcase的源码就不难发现问题了。
链接:https://ruby-doc.org/core-2.4.1/String.html,搜索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!的源码
链接:https://ruby-doc.org/core-2.4.1/String.html,搜索downcase!
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.
至此整个过程我们可以理解为:
- 有一个对象1,我们用a保存了他的引用。
- 然后我们将它的“引用的拷贝”传递给了方法pref3中的本地变量a,这时本地变量a保存了1对象的引用。
- 我们在pref3方法中创建了5对象,将其引用赋值给了本地变量a,这时a擦去了保存的1对象的引用,而改为保存5对象的引用
- 调用完pref3方法 ,其本地变量a随之消亡,对象5因为没有引用而随后被垃圾回收。
- 而外部的变量a自始至终保存着对象1的引用。
现在回头想想你的方法中传进去的a,b虽然交换了位置,但是对外部定义的a,b没有丝毫影响。因为他们根本保存的就是不同的对象的引用。
ruby传递的是 引用的拷贝 并不是引用的本身。(其实就可以理解为值传递)
但对于基本类型是直接传递对象本身的。举个例子:
可以参考这个http://www.ruby-doc.org/core-1.9/classes/Fixnum.html
写道
“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.“.
总结:Ruby里是值传递还是引用传递的更多相关文章
- Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义
一.Java中什么叫做引用类型变量?引用:就是按内存地址查询 比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...
- java中值传递和引用传递
最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...
- Java中的值传递和引用传递
这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...
- JavaScript 函数参数传递到底是值传递还是引用传递
tips:这篇文章是听了四脚猫的js课程后查的,深入的理解可以参看两篇博客: JavaScript数据类型--值类型和引用类型 JavaScript数据操作--原始值和引用值的操作本质 在传统的观念里 ...
- java中方法的参数传递机制(值传递还是引用传递)
看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参 ...
- java参数传递时到底是值传递还是引用传递
java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...
- Java面向对象-方法的值传递和引用传递
Java面向对象-方法的值传递和引用传递 0 发布时间:『 2016-08-21 14:21』 博客类别:Java核心基础 阅读(197) 评论(0) Java面向对象-方法的值传递和引用传递 方 ...
- String是值传递还是引用传递
String是值传递还是引用传递 今天上班时,同事发现了一个比较有意思的问题.他把一个String类型的参数传入方法,并在方法内改变了引用的值. 然后他在方法外使用这个值,发现这个String还是之前 ...
- 堆栈详解 + 彻底理解Java的值传递和引用传递
本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...
- JAVA不可变类与可变类、值传递与引用传递深入理解
一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: P ...
随机推荐
- NSE入门--nmap 脚本基础
- <embed> 标签
<embed> 标签定义嵌入的内容,比如插件. <embed quality="high" bgcolor="#FFF" wmode=&quo ...
- mysql的一些高级查询
1,查出学生详情表性别为男,并同时年龄大于18的 2,根据上述的结果,查出学生表对应的姓名,年龄,性别,address 3,查出学生的(姓名,年龄,性别,所属学院) 还可以添加注释
- 【Codeforces 1106D】Lunar New Year and a Wander
[链接] 我是链接,点我呀:) [题意] 让你遍历n个节点,访问过的节点不操作. 如果是没有访问过的点,那就把它加到序列的末尾. 问你形成的最小字典序的序列是多少. [题解] 显然每次找最小的标号 用 ...
- bcd(Binary-Coded Decimal缩写)
Binary-Coded Decimal,简称BCD,称BCD码或二-十进制代码,亦称二进码十进数.是一种二进制的数字编码形式,用二进制编码的十进制代码.这种编码形式利用了四个位元来储存一个十进制的 ...
- N天学习一个linux命令之rpm
用途 RPM是Redhat Package Manager三个单词首字母缩写,是类redhat linux系统的包管理器,用它可以安装包(二进制/源码),升级包,删除包,查询包信息等功能.RPM软件包 ...
- OpenCV+iOS开发使用文档
一. 前言 OpenCV是开源的跨平台的计算机视觉库,实现了图像处理.计算机视觉和机器学习的很多通用算法. 对于移动设备没有快速输入的键盘,大的屏幕,其优势在于图像和声音,因此要 ...
- Android:创建无标题栏的Activity
上图是一个带标题栏的Activity.有些时候我们希望能去除这个标题栏,做法如下: 1. 在res/values目录下面创建styles.xml.如果你已经有这个文件了,那么直接打开这个文件,添加如下 ...
- PHP array_chunk()
定义和用法 array_chunk() 函数把一个数组分割为新的数组块. 其中每个数组的长度由参数 size 决定. 可选参数 preserve_key 是一个布尔值,它指定新数组是否使用原数组相同的 ...
- poj 1635
有根树同构.参考论文<hash在....> #include <iostream> #include <fstream> #include <algorith ...