即使在了解Scala(What is Scala's static overloading rule?)中的静态重载后,我仍然无法将其用于<:<
类。
此类用于检查子类,并在Predef
:
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
但是当我写A <:< B
时,我不确定我是否使用<:<[A,A]
或<:<[B,B]
的实例,因为遵循静态重载规则既不比另一个更具体。
我们首先尝试这一点,以确保它真的有效,用我的<:<
替换mycic
:
class superC
class subC extends superC
abstract class mycic[-From,+To] extends ((From) => To) with Serializable
object Main extends App {
implicit def FandT[A]: mycic[A,A] = new (mycic[A,A]) { def apply(x: A) ={x}}
val e = implicitly[subC mycic superC]
val a = new subC
e.apply(a)
}
这很顺利。但是当我们尝试定义它正在使用的那个时:
class superC
class subC extends superC
abstract class mycic[-From,+To] extends ((From) => To) with Serializable
object Main extends App {
implicit val FF : mycic[subC,subC] = new(mycic[subC,subC]){def apply(x:subC) ={println("FF");x}}
implicit val TT : mycic[superC,superC] = new(mycic[superC,superC]){def apply(x:superC) ={println("TT");x}}
val e = implicitly[subC mycic superC]
val a = new subC
e.apply(a)
}
我们收到以下编译错误:
Main.scala:10: error: ambiguous implicit values:
both value TT in object Main of type => mycic[superC,superC]
and value FF in object Main of type => mycic[subC,subC]
match expected type mycic[subC,superC]
val e = implicitly[subC mycic superC]
^
在运行的代码中使用了哪个mycic
隐式实例?为什么在第二个示例中它的行为有所不同?
答案 0 :(得分:0)
您可以使用打印标签完成功能查看类型:
$(".myselect").select2().select2("val", null);
$('#test').val('<?php echo $previouschoice;?>').trigger('change');
(向右滚动以见证scala> def f[A,B](a: A, b: B)(implicit ev: A <:< B) = ev
f: [A, B](a: A, b: B)(implicit ev: <:<[A,B])<:<[A,B]
scala> trait X ; trait Y extends X
defined trait X
defined trait Y
scala> f(null.asInstanceOf[Y], null.asInstanceOf[X]) //print
$line3.$read.$iw.$iw.f[Y, X](null.asInstanceOf[$line4.$read.$iw.$iw.Y], null.asInstanceOf[$line4.$read.$iw.$iw.X])(scala.Predef.$conforms[Y]) // : <:<[Y,X]
作为隐式调用。)
scala.Predef.$conforms[Y]
方法只是一个身份函数。由于功能的差异:
conforms
因此,如果scala> implicitly[(Y => Y) <:< (Y => X)]
res0: <:<[Y => Y,Y => X] = <function1>
scala> f(null.asInstanceOf[Y], null.asInstanceOf[X])
res1: <:<[Y,X] = <function1>
scala> .apply(null.asInstanceOf[Y])
res2: X = null
符合Y
,我可以使用X
您要求的Y => Y
。同样适用于Y => X
。
模棱两可的例子是因为两个隐式val都不符合另一个(因为类型参数的反对和共方差)。否则,一个val将被选为更具体的。
编辑:您可以使用<:<
来观察类型推断,这是它选择未指定的类型arg的方式。在此,它推断-Ytyper-debug
,因为预期类型为$conforms[Y]
:
<:<[Y,X]
如果您指定| | | | solving for (A: ?A, B: ?B)
| | | | [search #1] start `[A, B](a: A, b: B)(implicit ev: <:<[A,B])<:<[A,B]`, searching for adaptation to pt=<:<[Y,X] (silent: value res0 in $iw) implicits disabled
| | | | [search #1] considering $conforms
| | | | solving for (A: ?A)
| | | | [adapt] $conforms adapted to [A]=> <:<[A,A] based on pt <:<[Y,X]
| | | | [search #1] success inferred value of type <:<[Y,X] is SearchResult(scala.Predef.$conforms[Y], )
| | | | |-- [A, B](a: A, b: B)(implicit ev: <:<[A,B])<:<[A,B] EXPRmode (site: value res0 in $iw)
| | | | | \-> <:<[Y,X]
,则同样会使用f[X,X]
。