为什么带有映射的隐式会产生 Range 语句错误?
Why does an implicit with a map yield a Range statement error?
对于下面的 MRE,我希望得到以下输出:
$ scala mre.scala
1
object Main {
def main(args: Array[String]): Unit = {
implicit val thing = List[String]().map(_.to(List))
for (x <- 1 to 1) {
println(x)
}
}
}
但是我得到的是以下内容
$ scala mre.scala
mre.scala:4: error: type mismatch;
found : Int(1)
required: scala.collection.Factory[Char,?]
for (x <- 1 to 1) {
如果我删除 implicit
或 .map(_.to(List))
那么它会按预期工作。
这到底是怎么回事?我什至不知道从哪里开始。
$ scala --version
Scala code runner version 2.13.7 -- Copyright 2002-2021, LAMP/EPFL and Lightbend, Inc.
有根据的猜测(99% 的确定性):任何集合都会扩展 (Partial
)Function
因此,通过使集合隐式化,您将提供隐式转换(因为任何一元 implicit def
OR隐式函数是隐式转换):
// this
implicit val thing = List[String]().map(_.to(List))
// implies this
implicit def intToCharList(idx: Int): List[Char]] = thing(idx)
然后这里:
1 to 1
你有歧义:可能是:
- 扩展方法
.to(Int)
Int
- 在
Int
隐式转换后 List
上的 .to(CollectionType)
普通方法(自 Scala 2.13 起)
如果编译器选择后者,那么你会得到类似
的东西
thing(1).to(1) // .to expects collection factory and got 1 instead
这会触发您看到的错误。它可能会选择后者,因为你在同一范围内声明了你的隐式,而 richInt
implicit conversion 在 scala.Predef
中的 LowPriorityImplicit
中声明,所以 Scala 会更喜欢你的。
在 Scala 3 中,隐式转换是 Function
的 子类型 ,因此不会发生此问题。在 Scala 2 中,我只能强烈建议不要使 any 集合隐式化。
对于下面的 MRE,我希望得到以下输出:
$ scala mre.scala
1
object Main {
def main(args: Array[String]): Unit = {
implicit val thing = List[String]().map(_.to(List))
for (x <- 1 to 1) {
println(x)
}
}
}
但是我得到的是以下内容
$ scala mre.scala
mre.scala:4: error: type mismatch;
found : Int(1)
required: scala.collection.Factory[Char,?]
for (x <- 1 to 1) {
如果我删除 implicit
或 .map(_.to(List))
那么它会按预期工作。
这到底是怎么回事?我什至不知道从哪里开始。
$ scala --version
Scala code runner version 2.13.7 -- Copyright 2002-2021, LAMP/EPFL and Lightbend, Inc.
有根据的猜测(99% 的确定性):任何集合都会扩展 (Partial
)Function
因此,通过使集合隐式化,您将提供隐式转换(因为任何一元 implicit def
OR隐式函数是隐式转换):
// this
implicit val thing = List[String]().map(_.to(List))
// implies this
implicit def intToCharList(idx: Int): List[Char]] = thing(idx)
然后这里:
1 to 1
你有歧义:可能是:
- 扩展方法
.to(Int)
Int
- 在
Int
隐式转换后List
上的.to(CollectionType)
普通方法(自 Scala 2.13 起)
如果编译器选择后者,那么你会得到类似
的东西thing(1).to(1) // .to expects collection factory and got 1 instead
这会触发您看到的错误。它可能会选择后者,因为你在同一范围内声明了你的隐式,而 richInt
implicit conversion 在 scala.Predef
中的 LowPriorityImplicit
中声明,所以 Scala 会更喜欢你的。
在 Scala 3 中,隐式转换是 Function
的 子类型 ,因此不会发生此问题。在 Scala 2 中,我只能强烈建议不要使 any 集合隐式化。