scala - scala中的奇怪类型推断

标签 scala dictionary type-inference

我在 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) => ()

两个表达式不应该是不同的类型吗?还是涉及到一些隐式类型转换?

最佳答案

原来的编译错误

编译错误是因为这个函数:

(a: Any) => Unit

属于类型

Any => Unit.type

并且不是的类型:

Any => Unit

换句话说,您正在返回 Unit , Unit 类型的伴生对象。该伴生对象的类型为 Unit.type,它与 Unit 的类型不同(这适用于 Scala 中的所有伴生对象)。

您需要实际返回一个 Unit 类型的值。 As outlined in the docs , 唯一这样的值是 ()

所以,你的默认函数应该是:(a: Any) => ().


编辑:关于补充问题。

单位换算

这里:

val a: Any => Unit = (a: Any) => Unit

您正在显式键入表达式以具有 Unit 的返回类型。通常它会导致类型错误,但是(正如您所怀疑的)“幸运”您触发了 one of the pre-defined implicit value conversions ,具体来说:

Value Discarding

If e has some value type and the expected type is Unit, e is converted to the expected type by embedding it in the term { e; () }.

所以,这个:

(a: Any) => Unit  //return type is Unit.type

变成:

(a: Any) => {Unit; ();} //return type is Unit

请注意,根据定义,转换适用于任何值,例如val c: Unit = "c" 产生相同的结果。

关于scala - scala中的奇怪类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34131642/

相关文章:

Python-将键值部分添加到空字典中

intellij-idea - 我如何知道 Kotlin 中的推断类型?

generics - Dart 泛型类实例化

Python排序多个属性

mysql - Scala Play 2.4.x 通过异常 (MySQL) 处理扩展字符到 Java Mail

scala - 如何将kafka流转换为spark RDD或Spark Dataframe

scala - 为什么我的 akka 日志在游戏中不起作用

Python:使用 .item() 打印字典时出错

java - 使用 Java Guava 库,如何使用 Builder 创建 ImmutableSortedSet?

scala - SBT 错误 : java. lang.RuntimeException:未检测到主类