5

我是 Ruby 和这个网站的新手。

下面两个函数是不同的,一个改变函数外的变量,一个不改变。

def m1 (x)
  x << "4"
end

def m2 (x)
  x = x + "4"
end


str="123"

m2(str)   #str remains unchanged 123

m1(str)   #str is changed to 1234

我想确保我正确理解这一点 -

当调用 m1 时,对 str 的引用被复制并传递给将其视为 x 的函数。运算符 << 更改引用原始 str 的 x ,因此此操作会更改 str 。

当调用 m2 时,对 str 的引用被复制并传递给将其视为 x 的函数。运算符 + 创建一个新字符串,赋值 x = x + "4" 只是将 x 重定向到新字符串,而原始 str 变量保持不变。

对?

谢谢

方法声明和调用

4

3 回答 3

10

String#+:: str + other_str → new_strConcatenation - 返回一个包含other_str连接到的新字符串str

String#<<:: str << integer → str: Append - 将给定对象连接到str.

<<不创建新对象,就像+那样。

a = "str"
#=> "str"
a.object_id
#=> 14469636
b = a << "ing"
#=> "string"
a.object_id
#=> 14469636
b.object_id
#=> 14469636

a=  "str"
#=> "str"
b = a + "ing"
#=> "string"
a.object_id
#=> 16666584
b.object_id
#=> 17528916

编辑

从你的评论中,明白了你的意思。见下文:

def m1 (x)
 x << "4"
end
#=> nil
def m2 (x)
 x = x + "4"
end
#=> nil

str="123"
#=> "123"

m2(str)
#=> "1234"

str
#=> "123"

当您在方法内部传递值时,此处str没有更改m2(),所有更改都根据上述调用在方法中进行。因此下面str没有显示该更改。要查看更改,您必须按如下方式调用它。

str = m2(str)
#=> "1234"

str
#=> "1234"

或者

您可以执行以下操作:- 我传递了参考地址str但没有传递值。

str = "abc"
#=> "abc"
str.object_id
#=> 16250484
ObjectSpace._id2ref(16250484)
#=> "abc"
def m1 (x)
ObjectSpace._id2ref(x) << "4"
end
#=> nil
m1(16250484)
#=> "abc4"
str
#=> "abc4"

希望它有意义:)

干杯!

于 2013-03-17T14:41:46.953 回答
2

<<连接运算符对字符串具有破坏性。这意味着它将操纵它所作用的变量,而不仅仅是返回表达式的结果。

例子:

str = "abc"
puts str + "d" # "abcd"

puts str # "abc"

puts str << "d" # "abcd"

puts str # "abcd"
于 2013-03-17T15:00:43.540 回答
1

下面两个函数是不同的,一个改变函数外的变量,一个不改变。

这是错误的。两种方法(它们是方法,顺便说一句,不是函数,Ruby 没有函数;存在根本区别)都不会改变str变量。m1修改变量指向的对象,但这与修改变量本身完全不同。

于 2013-03-18T10:58:09.790 回答