如果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
必须在*
运算符之前以避免引发错误?
-
你的后一个片段中有一个错别字:它应该以
x = 6
开头(不带引号(。 -
Ruby中的所有东西都是一个对象,包括
String
、Integer
的实例,甚至是nil
NilClass
的实例。
也就是说,不仅仅是一个运营商*
。这是一个普通的老式好方法,在不同的类上声明,由运算符*
调用(感谢@SergioTulentsev挑剔的措辞评论。这是String#*
的文档,您可能会发现自己的其他文档。"a" * 6
别无他法,无非是:
"a".*(6)
您可以在控制台中检查上述内容:这是一个完全有效的 Ruby 代码。因此,不同的类对*
方法有不同的实现,因此上面的结果不同。
您在这里尝试三种模式:
- 一个。
string * numeric
- 二.
numeric * string
- 三.
numeric * numeric
方法的行为和需要的参数主要取决于定义方法的方法左侧的内容(在本例中为*
(。没有一种方法(包括*
(本身是可交换的。
String#*
要求第一个参数是数字,a. 满足,Numeric#*
要求第一个参数是数字,c. 满足,而 b. 不满足。
您需要了解*
的方法的作用。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" 等等。例如,"*"、"~"、"[]"和"[]="是有效的方法名称">