总结: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 ...
随机推荐
- 洛谷P1598 垂直柱状图
模拟题...我自己一直被光标下去上不去怎么模拟困扰,实际上可以直接从高到低,从左到右模拟 我的代码(算法借鉴题解) #include <bits/stdc++.h> using names ...
- C#关键字详解第一节
abstract:抽象类: 他表达对问题或者实际中的事物,对象等所设计出的抽象概念,比如一个灵感.生物等,这些都是抽像, 但是他们往往也有具体的指向,比如生物圈有人类,猴子,老虎等等,老虎和人类是实际 ...
- Android传递Bitmap的两种简单方式及其缺陷
Android传递Bitmap的几种简单方式 一,通过Intent的Bundle. 比如有两个activity,A,B,从A进入B.先在A中将Bitmap写进去: Resources res=getR ...
- [cogs729] [网络流24题#5] 圆桌聚餐 [网络流,最大流,多重二分图匹配]
建图:从源点向单位连边,边权为单位人数,从单位向圆桌连边,边权为1,从圆桌向汇点连边,边权为圆桌容量. #include <iostream> #include <algorithm ...
- hdu_1040_As Easy As A+B_201308191751
As Easy As A+B Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- WebGIS开发技术杂谈
WebGIS项目的开发主要是B/S架构.最流行的是clientjavascript,server端java. 另外还有flexclient. client主要完毕用户交互.向server端发送请求并传 ...
- Android之怎样使用ListView列表视图
ListView 列表视图创建方法: (1)直接使用ListView 组件创建 (2)让Activity继承ListActivity实现 第一种:在XML中直接使用ListView 组件创建 在val ...
- DOS命令将黑框中查询到的信息保存到TXT等文件里
- UVALive - 6910 (离线逆序并查集)
题意:给处编号从1~n这n个节点的父节点,得到含有若干棵树的森林:然后再给出k个操作,分两种'C x'是将节点x与其父节点所连接的支剪短:'Q a b'是询问a和b是否在同一棵树中. 题解:一开始拿到 ...
- Codeforces Round #250 Div. 2(C.The Child and Toy)
题目例如以下: C. The Child and Toy time limit per test 1 second memory limit per test 256 megabytes input ...