我试图理解scala在scala.Predef中实现从sub到super类型的默认类型转换的机制。从文献中我收集到这是通过函数
完成的implicit def conforms[A] = new A<:<A { def apply(a:A)=a }
无参数函数conforms [A]仅返回隐式转换A =&gt; B. 函数值(作为类型A =&gt; A的可调用类型,因此类型A =&gt; B,当A&lt;:B时)。
但是,当编译器查找隐式类型转换时,它需要一个隐式值 类型A => B的类型不是返回这样的值的函数。因此我的问题是:
从A =&gt; B中寻找默认类型转换时,其中A&lt;:B,编译器如何 从函数中获取符合[A]到其唯一值。
答案 0 :(得分:1)
隐式解决方案也寻求子类型,A <: B
=&gt; A => A <: A => B
,如List[Int] <: Seq[Int]
。
scala> :paste
// Entering paste mode (ctrl-D to finish)
implicit val x: List[Int] = List(1, 2, 3)
def f(implicit x: Seq[Int]): Int = x.head
f
// Exiting paste mode, now interpreting.
x: Seq[Int] = List(1, 2, 3)
f: (implicit x: Seq[Int])Int
res1: Int = 1
因此,在进行类型转换时,我们会使用A => B
查找A <: B
,A => A
适合。
我不确定我是否理解你,但在搜索所需类型的值时会遵循defs
。函数是否需要零个,一个或多个参数并不重要。例如,零:
implicit def implicitList[A]: List[A] = List() //the only obvious case
scala> implicitly[Seq[Int]]
// res0: Seq[Int] = List()
或者两个:
case class Foo(str: String)
case class Bar(str: String)
case class Quux(str: String)
implicit val foo = Foo("foo")
implicit val bar = Bar("bar")
// how to build quux:
implicit def quux(implicit foo: Foo, bar: Bar): Quux = Quux(foo.str + bar.str)
implicitly[Quux]
// res2: Quux = Quux(foobar)
如果我们添加以下任何内容:
implicit def quux2(implicit quux: Quux): Quux = quux
implicit def quux3(implicit foo: Foo): Quux = Quux(foo.str)
implicit val quux4: Quux = Quux("quux")
implicit def quux5[A]: Quux = Quux("poly")
我们对Quux
:
scala> implicitly[Quux]
<console>:29: error: ambiguous implicit values:
both method quux of type (implicit foo: Foo, implicit bar: Bar)Quux
and method quux2 of type (implicit quux: Quux)Quux
match expected type Quux
implicitly[Quux]
^
即。范围中只有一个def
或val
可以返回我们感兴趣的类型。这很容易静态验证。
但是如果其中任何一个是范围内唯一的那个,它们就会起作用。