[英]Scala typeclasses implicit resolution
(Scala 2.11.8) (斯卡拉2.11.8)
Consider the following code: 请考虑以下代码:
object ScalaTest extends App {
class Wrapper {
import Wrapper._
def init(): Unit = {
// "could not find implicit value for parameter tc: ScalaTest.Wrapper.TC[Int]"
printWithTC(123)
// Compiles
printWithTC(123)(IntTC)
// Compiles again!
printWithTC(132)
}
}
object Wrapper {
trait TC[A] {
def text(a: A): String
}
implicit object IntTC extends TC[Int] {
override def text(a: Int) = s"int($a)"
}
def printWithTC[A](a: A)(implicit tc: TC[A]): Unit = {
println(tc.text(a))
}
}
(new Wrapper).init()
}
I have a bunch of questions regarding this piece of code: 关于这段代码,我有很多问题:
IntTC
get resolved in the first place? 为什么IntTC
不IntTC
得到解决? Use a val
with a explicit return type. 使用具有显式返回类型的val
。 See https://github.com/scala/bug/issues/801 and https://github.com/scala/bug/issues/8697 (among others). 请参阅https://github.com/scala/bug/issues/801和https://github.com/scala/bug/issues/8697 (以及其他内容)。
Implicit objects have the same issue as implicit vals and defs with inferred return types. 隐式对象与隐式val和defs具有相同的问题,具有推断的返回类型。 As for your second question: when IntTC
is used explicitly you force the compiler to typecheck it, so after that point its type is known and can be found by implicit search. 至于你的第二个问题:当显式使用IntTC
时,你强制编译器对它进行类型检查,所以在那之后它的类型是已知的并且可以通过隐式搜索找到。
class Wrapper {
import Wrapper._
def init(): Unit = {
// Compiles
printWithTC(123)
// Compiles
printWithTC(123)(IntTC)
// Compiles
printWithTC(132)
}
}
object Wrapper {
trait TC[A] {
def text(a: A): String
}
implicit val IntTC: TC[Int] = new TC[Int] {
override def text(a: Int) = s"int($a)"
}
def printWithTC[A](a: A)(implicit tc: TC[A]): Unit = {
println(tc.text(a))
}
}
If you really want your implicit to be evaluated lazily like an object, you can use an implicit lazy val
with an explicit type. 如果你真的希望像对象那样implicit lazy val
地对你的隐式进行求值,你可以使用带有显式类型的implicit lazy val
。
Define the implicit before the use of it. 在使用之前定义隐式。
object Wrapper {
trait TC[A] {
def text(a: A): String
}
implicit object IntTC extends TC[Int] {
override def text(a: Int) = s"int($a)"
}
def printWithTC[A](a: A)(implicit tc: TC[A]): Unit = {
println(tc.text(a))
}
}
class Wrapper {
import Wrapper._
def init(): Unit = {
// "could not find implicit value for parameter tc: ScalaTest.Wrapper.TC[Int]"
printWithTC(123)
// Compiles
printWithTC(123)(IntTC)
// Compiles again!
printWithTC(132)
}
}
(new Wrapper).init()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.