Scala 的“::”运营商,它是如何工作的?
在 Scala 中,我可以创建一个 caseclass,case class Foo(x:Int)
,然后将其放入列表中,如下所示:
List(Foo(42))
现在,这里没什么奇怪的。以下内容对我来说很奇怪。运算符 ::
是列表上的函数,对吧?对于 Scala 中任何带有一个参数的函数,我都可以使用中缀表示法来调用它。 例如,1 + 2
是对象 Int
上的函数 (+)
。我刚刚定义的类 Foo
没有 ::
运算符,那么下面的情况怎么可能呢?
Foo(40) :: List(Foo(2))
在 Scala 2.8 RC1 中,我从交互式提示中得到以下输出:
scala> case class Foo(x:Int)
defined class Foo
scala> Foo(40) :: List(Foo(2))
res2: List[Foo] = List(Foo(40), Foo(2))
我可以继续使用它,但解释是什么?
In Scala, I can make a caseclass, case class Foo(x:Int)
, and then put it in a list like so:
List(Foo(42))
Now, nothing strange here. The following is strange to me. The operator ::
is a function on a list, right? With any function with one argument in Scala, I can call it with infix notation.
An example is 1 + 2
is a function (+)
on the object Int
. The class Foo
I just defined does not have the ::
operator, so how is the following possible?
Foo(40) :: List(Foo(2))
In Scala 2.8 RC1, I get the following output from the interactive prompt:
scala> case class Foo(x:Int)
defined class Foo
scala> Foo(40) :: List(Foo(2))
res2: List[Foo] = List(Foo(40), Foo(2))
I can go on and use it, but what is the explanation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从规格来看:
在程序经过编译器的“typer”阶段后,您始终可以通过打印程序来了解这些规则如何在 Scala 中应用:
From the Spec:
You can always see how these rules are applied in Scala by printing the program after it has been through the 'typer' phase of the compiler:
它以
:
结尾。这就是标志,该函数是在右侧的类中定义的(在此处的List
类中)。因此,它是
List(Foo(2)).::(Foo(40))
,而不是Foo(40).::(List(Foo(2)))
在你的例子中。It ends with a
:
. And that is the sign, that this function is defined in the class to the right (inList
class here).So, it's
List(Foo(2)).::(Foo(40))
, notFoo(40).::(List(Foo(2)))
in your example.给出的答案中缺少的一个方面是支持模式匹配表达式中的
::
:定义了一个类 :: :
所以
case ::(x,xs)
会产生相同的结果。表达式case x :: xs
有效,因为默认提取器::
是为 case 类定义的,并且可以中缀使用。One aspect missing in the answers given is that to support
::
in pattern matching expressions:A class :: is defined :
so
case ::(x,xs)
would produce the same result. The expressioncase x :: xs
works because the default extractor::
is defined for the case class and it can be used infix.如果方法名称以冒号 (
:
) 结尾,则在 上调用该方法右操作数,这里就是这种情况。如果方法名称不以冒号结尾,则在左侧操作数上调用该方法。例如,a + b
、+
在a
上调用。因此,在您的示例中,
::
是其右侧操作数(即List
)上的方法。If the method name ends with a colon (
:
) the method is invoked on the right operand, which is the case here. If the method name doesn't end with colon, the method is invoked on the left operand. For example,a + b
,+
is invoked ona
.So, in your example,
::
is a method on its right operand, which is aList
.