Scala里的1 :: 2 :: 3 :: Nil是什么鬼?

如题所述

第1个回答  2022-06-01
先说结论:你会得到一个装了“1 2 3”三个元素的列表。

不过,对于Java程序员来说,这应该是一种很陌生的用法。

在《同样是访问数组的第一个元素,为什么Scala选择不用array[0]?》中我们讲到Scala是有不少“糖”的,比如1 + 2实际上等同于对“1”这个Int类型调用了“+”这个方法,并且传入“2”这个参数,也就是:(1).+(2)。

那么在这里,可以尝试推导下,1 :: 2是不是等于(1).::(2)呢?很可惜并不是。实际上标题里的语句应该倒着执行,也就是说,实际上是先执行了Nil.::(2)。这条语句得到的结果是一个仅包含了2这个元素的列表。

因此 :: 代表的是,把某样东西和某个列表拼接在一起,并返回一个新的列表。

这里的 :: 我们读作cons,借鉴自老祖宗Lisp的语法,刚才的2 :: Nil在Lisp里我们写作(cons 2 '())。

看到这里,大概你也猜到Nil代表的是一个空列表了吧?

当然,这里除了借鉴了语法之外,还有一个很重要的点, 方法调用返回的其实是一个新的List,而不是在原来的List里进行头插。 也是之前一篇文章提到的不可变数据结构的一种应用。

不得不赞一下,Scala给了大家一个启示:Lisp也是可以不要括号的!

(如果有人想看关于Lisp的东西,请在文章下方留个言哦)

同样是把方法调用转化为中缀表达式的语法糖,一会是对于操作符的左边执行方法调用,一会是对于操作符的右边执行方法调用,到底有什么便于记忆的规则么?

实际上,Martin在《Programming in Scala》里给出了答案:

简单说,除非是以冒号结尾的方法,否则一律像 a * b 这样处理。
相似回答