【发布时间】:2015-12-07 10:42:27
【问题描述】:
我在 Scala 类型推断方面遇到了一些问题。 在下面的工作表示例中,我定义了一个 Map,它将 Any 值映射到返回 Unit 值的函数。
有趣的是,当我尝试仅使用一行代码定义同一个映射时,它不起作用,因为“bar”函数的返回类型突然变为 Any 而不是 Unit。
type UnitFun = (Any) => Unit
val foo = "foo"
val bar = (a: Any) => System.out.println("bar")
val map: Map[Any, UnitFun] = Map().withDefaultValue(((a: Any) => Unit))
val doesCompile: Map[Any, UnitFun] = map + (foo -> bar)
val doesNotCompile: Map[Any, UnitFun] = Map().withDefaultValue(((a: Any) => Unit)) + (foo -> bar)
我将 IDEA14 用作 Scala 2.11.6 的 IDE
在我看来这是 Scala 编译器的功能/错误,还是我遗漏了什么?
顺便说一句,我刚刚注意到,当我像这样在 'doesNotCompile' 中使用 'bar' 作为默认值时:
val doesCompileNow: Map[Any, UnitFun] = Map().withDefaultValue(bar) + (foo -> bar)
它似乎突然起作用了,我现在很困惑。 :D
编辑 1: @Mikolak
在这种情况下,下面的代码是如何工作的? :)
val a: Any => Unit = (a: Any) => Unit
val b: Any => Unit = (a: Any) => ()
两个表达式不应该是不同的类型吗?还是涉及到一些隐式类型转换?
【问题讨论】:
-
添加了有关您的编辑的说明。请注意,这是一种与原始现象完全正交的现象。
-
已经看过了,我认为从 Unit.type 到 Any 的隐式转换(根据 intellij 输出)是让我偏离轨道的原因这个。我认为这只是另一个隐式转换。 :)
-
接下来要补充一点:不信任 IntelliJ 的语法检查。虽然慢慢变得更好,但它仍然有输出误报和漏报的倾向。换句话说,当你遇到一个奇怪的错误时,你的第一个行动应该是运行
sbt compile。 -
我现在知道我使用 'Unit' 而不是 '()' 犯了一个错误,但有趣的是,根据我编写代码的方式,这些隐式转换会导致不同的类型(第一段代码)。 ^^
-
是的,当语言的输入既强大又不显眼时,这就是要付出的代价——在这样的极端情况下,你一定会得到看似不直观的结果。
标签: scala dictionary type-inference