了解Scala中的infix方法调用和cons运算符(::) [英] Understanding infix method call and cons operator(::) in Scala

查看:180
本文介绍了了解Scala中的infix方法调用和cons运算符(::)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Scala编程语言还很陌生,在我按照

I'm quite new to Scala programming language, and was trying something out stucked in my mind while I was following the lecture notes at here.

我认为我不太了解cons运算符的工作原理,这是我尝试过的一些事情:

I think I couldn't really understand how cons operator works, here are some things I tried:

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

I've created a pseudo-random number generator, then tried to create a list of one random value:

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方法.当我使用假肢时,没有问题

But it tried to pass List(3) to nextnt method. When i used paratheses, there was no problem

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

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

I was curious about the execution order, so i created a function to check it

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"功能有关,然后我尝试了以下操作:

As seen in outputs, execution order is the same as the order of appearance. Then I thought it might be about the 'nextInt' function, then I tried following:

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

它首先执行加法,然后执行cons.所以这是一个问题:gen nextInt 3 :: Nil1 + 2 :: Nil有什么区别?

It first executed addition, and after that cons is executed. So here is the question: What is the difference between gen nextInt 3 :: Nil and 1 + 2 :: Nil?

推荐答案

此处有两点值得关注:优先级固定性.如sepp2k所述,有关堆栈溢出的问题解释了优先级,认为所引用的规则不够完整,并且从Scala 2.7到Scala 2.8的变化很小.不过,差异主要涉及以=结尾的运算符.

There are two things of concern here: precedence and fixity. As sepp2k mentioned, this question on Stack Overflow explains the precedence, thought the rules, as quoted, are not complete enough, and there were very small changes from Scala 2.7 to Scala 2.8. Differences concern mostly operators ending in =, though.

关于固定性,Scala中的几乎所有内容都是从左到右读取的,这是程序员习惯的.但是,在Scala中,以:结尾的运算符从右到左读取.

As for fixity, almost everything in Scala is read left to right, which is what programmers are used to. In Scala, however, operators ending in : are read right to left.

那么,举这个例子:

1 + 2 :: Nil

首先,优先.什么是最优先的+:?根据该表,+的优先级高于:,因此首先进行加法.因此,表达式等于:

First, precedence. What has most precedence, + or :? According to the table, + has precedence over :, so the addition is done first. Therefore, the expression is equal to this:

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

现在没有优先级冲突,但是由于:::结尾,因此具有不同的固定性.它是从右到左读取的,因此:

Now there's no precedence conflict, but since :: ends in :, it has a diferent fixity. It is read right to left, therefore:

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

另一方面,在此:

gen nextInt 3 :: Nil

运算符::的优先级高于nextInt,因为:的优先级高于所有字母.因此,记住它的固定性,它变为:

The operator :: has precedence over nextInt, because : has precedence over all letters. Therefore, and remembering its fixity, it becomes:

gen nextInt Nil.::(3)

然后成为

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

这时错误很明显.

PS:我写的是(1).+(2)而不是1.+(2),因为在撰写本文时,1.被解释为双精度数,使1.+(2)成为将双精度1.0加上2的中缀表达式.从Scala 2.10.0开始不推荐使用此语法,并且在Scala 2.11中可能不存在.

PS: I'm writing (1).+(2) instead of 1.+(2) because, at the time of this writing, 1. is interpreted as a double number, making 1.+(2) an infix expression adding the double 1.0 to 2. This syntax is deprecated as of Scala 2.10.0, and will probably not be present on Scala 2.11.

这篇关于了解Scala中的infix方法调用和cons运算符(::)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆