为了账号安全,请及时绑定邮箱和手机立即绑定

Ruby是按引用传递还是按值传递?

/ 猿问

Ruby是按引用传递还是按值传递?

幕布斯5086720 2019-06-06 13:49:55

Ruby是按引用传递还是按值传递?

@user.update_languages(params[:language][:language1], 
                       params[:language][:language2], 
                       params[:language][:language3])lang_errors = @user.errors
logger.debug "--------------------LANG_ERRORS----------101-------------" 
                + lang_errors.full_messages.inspectif params[:user]
  @user.state = params[:user][:state]
  success = success & @user.saveendlogger.debug "--------------------LANG_ERRORS-------------102----------" 
                + lang_errors.full_messages.inspectif lang_errors.full_messages.empty?

@user对象将错误添加到lang_errors变量中的update_lanugages方法。当我对@user对象丢失最初存储在lang_errors变量。

虽然我试图做的更多的是一次黑客攻击(这似乎不起作用)。我想了解为什么变量值会被淘汰。我理解引用传递,所以我想知道如何在不被淘汰的情况下将值保存在变量中。


查看完整描述

3 回答

?
慕容708150

在传统术语中,Ruby严格按值传递。..但这不是你想要的。

Ruby没有任何纯、非引用值的概念,因此您当然不能将其传递给方法。变量总是引用对象。为了获得一个不会在您下面更改的对象,您需要使用DUP或克隆所传递的对象,从而给出一个没有其他人引用的对象。(尽管如此,这并不是防弹的-这两种标准的克隆方法都是浅拷贝的,因此克隆的实例变量仍然指向与原始对象相同的对象。如果象牙引用的对象发生了变异,那么它仍然会出现在副本中,因为它引用的是相同的对象。)


查看完整回答
反对 回复 2019-06-06
?
蝴蝶刀刀

其他答案都是正确的,但一位朋友要求我向他解释这一点,其实质在于Ruby是如何处理变量的,因此我想分享一下我为他写的一些简单的图片/解释(为篇幅而道歉,可能有些过于简单化):


Q1:当你给一个新变量赋值时会发生什么?str值为.'foo'?

str = 'foo'str.object_id # => 2000

enter image description here

A:一个叫做str创建指向对象的'foo',对于这个Ruby解释器的状态,它恰好位于内存位置。2000.


Q2:赋值现有变量时会发生什么?str使用=?

str = 'bar'.tap{|b| puts "bar: #{b.object_id}"} # bar: 2002str.object_id # => 2002


A:标签str现在指向另一个对象。


Q3:当你给一个新变量赋值时会发生什么?=str?

str2 = str
str2.object_id # => 2002


A:一个新的标签叫做str2创建,指向同一对象str.


Q4:如果被strstr2变了?

str2.replace 'baz'str2 # => 'baz'str  # => 'baz'str.object_id # => 2002str2.object_id # => 2002


答:两个标签仍然指向同一个对象,但该对象本身发生了变异(其内容已更改为其他内容)。


这与原来的问题有何关系?

这与Q3/Q4中的情况基本相同;该方法获得变量/标签的私有副本(str2)传递给它(str)。它不能更改标签的对象str 指点,但它可以更改.的内容它们都引用以包含Other的对象:

str = 'foo'def mutate(str2)
  puts "str2: #{str2.object_id}"
  str2.replace 'bar'
  str2 = 'baz'
  puts "str2: #{str2.object_id}"endstr.object_id # => 2004mutate(str) # str2: 2004, str2: 2006str # => "bar"str.object_id # => 2004


查看完整回答
反对 回复 2019-06-06
?
白衣染霜花

Ruby是按引用传递还是按值传递?

Ruby是按值传递的。一直都是。没有例外。如果没有。没有但是。

下面是一个简单的程序,它演示了这一事实:

def foo(bar)
  bar = 'reference'endbaz = 'value'foo(baz)puts "Ruby is pass-by-#{baz}"# Ruby is pass-by-value


查看完整回答
反对 回复 2019-06-06
  • 3 回答
  • 0 关注
  • 118 浏览
我要回答

相关问题推荐

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信