加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 带有后缀表示法的Range上的toList会导致类型不匹配

发布时间:2020-12-16 09:26:28 所属栏目:安全 来源:网络整理
导读:我刚刚开始使用Scala,并在Range和List上尝试了一些东西,我用一个非常简单的片段得到了一些非常奇怪的东西.我使用sublime来编辑和执行这些片段: val a = 1 to 10println(a) 产量 Range(1,2,3,4,5,6,7,8,9,10) 而 val a = 1 to 10val b = a toListprintln(a)
我刚刚开始使用Scala,并在Range和List上尝试了一些东西,我用一个非常简单的片段得到了一些非常奇怪的东西.我使用sublime来编辑和执行这些片段:

val a = 1 to 10
println(a)

产量

Range(1,2,3,4,5,6,7,8,9,10)

val a = 1 to 10
val b = a toList
println(a)

给我错误:

/home/olivier/Dropbox/Projects/ProjectEuler/misc/scala/ch05_ex02.scala:5:     error: type mismatch;
 found   : Unit
 required: Int
println(a)
       ^
one error found

相反,在REPL中,我没有收到任何错误. Scala版本是2.9.2

解决方法

这是由编译器解析 Suffix Notation的方式引起的(对于arity 0的方法).它将尝试将其解析为 Infix Notation(如果可能).这会导致编译器解析您的代码,如下所示:

val a = 1 to 10
val b = a toList println(a)

或者特别是带有点符号的后一行:

val b = a.toList.apply(println(a))

List [A]有一个apply方法,它采用类型为A的varargs(在本例中为Int),println返回Unit.这就是这个特定错误消息的原因.

根据Scala Documentation中的规定,这种风格令人不悦:

Suffix Notation

Scala allows methods of arity-0 to be invoked using suffix notation:

names.toList
// is the same as
names toList // Unsafe,don't use!

This style is unsafe,and should not be used. Since semicolons are optional,the compiler will attempt to treat it as an infix method if it can,potentially taking a term from the next line.

names toList
val answer = 42   // will not compile!

This may result in unexpected compile errors at best,and happily compiled faulty code at worst. Although the syntax is used by some DSLs,it should be considered deprecated,and avoided.

As of Scala 2.10,using suffix operator notation will result in a compiler warning.

建议使用点符号:

val b = a.toList

或者如果你真的想要,添加一个分号来表示行尾:

val b = a toList;

请注意,后者将发出编译器警告,如文档中所述:

[warn] postfix operator toList should be enabled
[warn] by making the implicit value scala.language.postfixOps visible.
[warn] This can be achieved by adding the import clause 'import scala.language.postfixOps'
[warn] or by setting the compiler option -language:postfixOps.
[warn] See the Scaladoc for value scala.language.postfixOps for a discussion
[warn] why the feature should be explicitly enabled.
[warn]   val b = a toList;
[warn]             ^
[warn] one warning found

In the REPL,on the contrary,I do not get any error.

因为REPL逐行执行.由于toList表达式未被println表达式取代,因此它将进行编译.如果您输入粘贴模式(:粘贴)并将其复制为代码块,您将看到相同的行为.

更多信息可以在Scala user-group question中找到

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读