理解Scala中的infix方法调用和conx运算符(::)

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (79)

我对Scala编程语言非常陌生,当我关注课堂讲稿的时候,我正在尝试一些塞在我脑海中的东西。

我想我无法真正理解CONS操作符是如何工作的,下面是我尝试过的一些事情:

我创建了一个伪随机数生成器,然后尝试创建一个包含一个随机值的列表:

scala> val gen = new java.util.Random
gen: java.util.Random = java.util.Random@1b27332

scala> gen nextInt 3 :: Nil
<console>:7: error: type mismatch;
 found   : List[Int]
 required: Int
       gen nextInt 3 :: Nil
                     ^

但是它试图将List(3)传递给Nextnt方法。当我使用Paratheses的时候,没有问题

scala> (gen nextInt 3) :: Nil
res69: List[Int] = List(1)

我对执行顺序很好奇,所以我创建了一个函数来检查它。

scala> def pr(i:Int):Int = { println(i); i }
pr: (i: Int)Int

scala> pr(1) :: pr(2) :: pr(3) :: Nil
1
2
3
res71: List[Int] = List(1, 2, 3)

从输出中可以看出,执行顺序与外观顺序相同。然后,我想它可能是关于‘nextInt’函数,然后我尝试如下:

scala> 1 + 2 :: Nil
res72: List[Int] = List(3)

它首先执行加法,然后执行CONCE。所以问题是:gen nextInt 3 :: Nil1 + 2 :: Nil?

提问于
用户回答回答于

正如sepp2k所提到的,这个关于堆栈溢出的问题解释了优先级,认为引用的规则不够完整,从Scala2.7到Scala2.8有非常小的变化。差异主要涉及操作符,以=尽管如此。

至于固定性,Scala中的几乎所有内容都从左到右读取,这正是程序员所习惯的。然而,在Scala中,操作符以:从右到左。

那么,以这个例子为例:

1 + 2 :: Nil

第一,优先权。最重要的是,+:?从桌子上看,+优先于:,所以加法是先完成的。因此,表达式等于:

((1).+(2)) :: Nil

现在没有优先冲突,但是::结束于:,它有一个不同的固定。因此,它从右到左读:

Nil.::((1).+(2))

另一方面,在这方面:

gen nextInt 3 :: Nil

操作员::优先于nextInt因为:优先于所有字母。因此,记住它的固定性,它就变成:

gen nextInt Nil.::(3)

然后变成

gen.nextInt(Nil.::(3))

在这一点上,错误是显而易见的。

用户回答回答于

这是关于优先级而不是执行顺序。+::,所以a + b :: c解析为(a + b) :: c。但是,带有常规名称的infix方法调用的优先级较低,因此a foo b c解析为a foo (b c)

扫码关注云+社区

领取腾讯云代金券