如果x
是非整数,我得到这个结果:
x = "a"
x * 6 #=> aaaaaa
6 * x #=> TypeError: String can't be coerced into Fixnum
如果x
是整数:
x = 6
x * 6 #=> 36
6 * x #=> 36
奇怪的是,如果x
是非整数,则乘法中的操作数顺序很重要,而x
是整数时则不然。有人可以解释这背后的理性是什么吗?当x
是字符串时,为什么变量x
必须位于*
运算符之前,以避免引发错误?
答案 0 :(得分:4)
您的后一段代码中有拼写错误:它应以x = 6
开头(不含引号。)
Ruby中的所有内容都是一个对象,包括String
,Integer
,甚至nil
的实例,它们是[{1}}的唯一实例。
那就是说,没有只是一个运营商 NilClass
。这是一个简单的旧方法,在不同的类上声明,由运算符*
调用(感谢@SergioTulentsev提供挑剔的措辞评论。)这是String#*
的文档,其他你可能会发现自己。 *
不是别的,而是:
"a" * 6
您可以在控制台中检查以上内容:它是完全有效的Ruby代码。因此,不同的类具有"a".*(6)
方法的不同实现,因此上面的结果不同。
答案 1 :(得分:4)
您正在尝试三种模式:
string * numeric
numeric * string
numeric * numeric
方法的行为和所需的参数主要取决于方法左侧的内容(本例中为*
),定义方法。没有方法(包括*
)本身是可交换的。
String#*
要求第一个参数为数字,即a。满足,Numeric#*
要求第一个参数为数字,c。满足,和b。没有。
答案 2 :(得分:3)
您需要了解方法*
的作用。 1 。这取决于方法的接收器。对于"cat".*(3)
,"cat"
是*
的接收者。对于1.*(3)
(如后面所述,可以编写,1*3
)1
是*
的接收者。术语“接收器”源于OOP向接收器发送消息(方法)的概念。
可以通过两种方式之一在对象(例如,"cat"
或1
)上定义方法。最常见的是该方法是在接收者的类上定义的实例方法(例如,*
或"cat".class #=> String
上定义的1.class #=> Integer
。第二种方式,这里不适用,是方法已在对象的单例类上定义,前提是该对象有一个。("cat"
有一个单例类,但是1
,是一个立即值,不会。)
因此,当我们看到"cat".*(3)
时,我们会查看String#*的文档并得出结论
"cat".*(3) #=> "catcatcat"
对于1*(3)
,我们期待Integer#*,它告诉我们
1.*(3) #=> 3
让我们尝试另一个:[1,2,3].*(3)
,因为[1,2,3].class #=> Array
我们期待Array#*并得出结论
[1,2,3].*(3) #=> [1, 2, 3, 1, 2, 3, 1, 2, 3]
请注意,此方法有两种形式,具体取决于其参数是整数(如此处)还是字符串。在后一种情况下
[1,2,3].*(' or ') #=> "1 or 2 or 3"
许多方法都有不同的行为,这取决于它的参数(以及是否提供了可选块)。
最后,Ruby允许我们使用这三种方法的简写(以及其他名称由不是字母,数字或下划线的字符组成的其他方法):
"cat"*3 #=> "catcatcat"
"cat" * 3 #=> "catcatcat"
1*3 #=> 3
[1,2,3] * 3 #=> [1, 2, 3, 1, 2, 3, 1, 2, 3]
这种速记通常被称为“语法糖”。
1 Ruby的方法名称不限于单词,例如“map”,“upcase” 等等。例如,“*”,“〜”,“[]”和“[] =”是有效的方法名称“