Scala 为什么将Seq转换为Set,然后在同一行上调用map不能编译
假设我定义以下代码:Scala 为什么将Seq转换为Set,然后在同一行上调用map不能编译,scala,Scala,假设我定义以下代码: val x: Seq[String] = Seq() val y = x.toSet.map(s => (s, true)) 这将无法编译,导致缺少参数类型错误 但如果我这样分解: val x: Seq[String] = Seq() val y = x.toSet val z = y.map(s => (s, true)) 它编译得很好。为什么会这样?请注意,适合哪种类型有多种选择 x.toSet[Any].map[(Any, Boolean]]((s:
val x: Seq[String] = Seq()
val y = x.toSet.map(s => (s, true))
这将无法编译,导致缺少参数类型错误
但如果我这样分解:
val x: Seq[String] = Seq()
val y = x.toSet
val z = y.map(s => (s, true))
它编译得很好。为什么会这样?请注意,适合哪种类型有多种选择
x.toSet[Any].map[(Any, Boolean]]((s: Any) => (s, true))
x.toSet[AnyRef].map[(AnyRef, Boolean]]((s: AnyRef) => (s, true))
x.toSet[String].map[(String, Boolean]]((s: String) => (s, true))
就像Scala 2应该做的那样
…选择最具体的值。但是由于函数是逆变的
在他们的论点中,当他们把Any
作为
一个参数,因此编译器无法决定
例如考虑如何因为参数逆变函数<代码>任意=> <代码>比<代码> String=>
更具体。implicitly[(Any => _) <:< (String => _)] // ok
toSet
可以拓宽类型,因此当您链接map
时,map
实际上需要一个新类型B>的函数:尚未定义的a
。当您将表达式分成两行时,编译器必须为B
提供一个类型,因为没有任何东西可以帮助它推断类型,所以它只是再次选择a
,因此下一个map
调用已经知道了类型。我相信Scala 3足够聪明,可以在这里做正确的事情。谢谢,我将重新观看视频,视频上说是2019年,但感觉就像十年前一样。
scala> Seq.empty[String].toSet.map(s => (s, true))
val res0: Set[(String, Boolean)] = Set()