Scala-带下界的泛型隐式

Scala-带下界的泛型隐式,scala,generics,implicit-conversion,implicit,Scala,Generics,Implicit Conversion,Implicit,考虑以下几点: class超级 类Sub扩展了Super 隐式val隐式选项:选项[Super]=None def[A,B>:A](A:A)(隐式i:Option[B])=println(“它工作了”) 如果我调用f(new Super),它可以正常工作,但是f(new Sub)会给我一个编译错误(找不到参数I的隐式值) 当A=Sub时,为什么不能将implicitOption用作隐式参数?在这种情况下,编译器需要一些帮助来确定使用哪个B。所以 f[Sub, Super](new Sub)

考虑以下几点:

class超级
类Sub扩展了Super
隐式val隐式选项:选项[Super]=None
def[A,B>:A](A:A)(隐式i:Option[B])=println(“它工作了”)
如果我调用
f(new Super)
,它可以正常工作,但是
f(new Sub)
会给我一个编译错误(找不到参数
I
的隐式值)


A=Sub
时,为什么不能将
implicitOption
用作隐式参数?

在这种情况下,编译器需要一些帮助来确定使用哪个
B
。所以

f[Sub, Super](new Sub)

很好用

---旧答案-仍然相关,但从不同角度出发-- 因为
选项
是协变的-这意味着您可以传递
选项[Sub]
,其中应传递
选项[Super]
,反之亦然

为了实现这一点,您需要一个逆变类(现在我们称它为
ContraOption
),这样您就可以在需要
ContraOption[Super]
的地方传递
ContraOption[Sub]

继续你的例子:

class Super
class Sub extends Super

implicit val implicitOption: Option[Super] = None

sealed abstract class ContraOption[-A]
case object ContraNone extends ContraOption[Any]
case class ContraSome[A](value: A) extends ContraOption[A]

implicit val implicitContraOption: ContraOption[Super] = ContraNone

def f[A, B >: A](a: A)(implicit i: Option[B]) = println("It worked")
def f2[A, B >: A](a: A)(implicit i: ContraOption[B]) = println("It worked 2")

f(new Super)  // It worked
f2(new Sub)   // It worked 2
请注意,尝试执行
f(new Sub)
(如您的示例所示)和
f2(new Super)
的编译都会失败,并出现“implicit not found”

有关协方差和逆变的更多基本理解,请参阅。但简单地说,协变泛型类“遵循”祖先-后代链接,而逆变型类则相反。要说明(在伪scala中):

class超级
类Sub扩展了Super
类协变[+A]
类逆变[-A]
这为我们提供了以下关系:

Sub解决方案是通过如下更改参数的定义,将参数
B
f
移动到
implicitOption


隐式定义隐式选项[B编译器没有任何输入来推断
B
。你到底想实现什么?好的,我想我明白你的意思,但是你能详细说明一下吗?取决于你真正想做什么/真正需要解决什么。我们可能会有一个解决方法。谢谢你的帮助,我想我明白你的意思。我从一个简单的问题开始,然后再重复一遍用
B
参数处理复杂的事情。不过现在用另一种方法解决了。在我的例子中,
Option[B]
应该在
B>:a
的地方出现。所以当
a
Sub
时,
None:Option[Super]
不会被接受吗?你是对的,更新了(更像是“重写,但保留旧的以备将来参考”:)这与问题大不相同。现在
隐式选项
Super
Sub
,以及
隐式选项
f()的类型参数是分离和无关的
现在是完全独立、不相关且无边界的。公平点。我已将类型参数编辑为
implicitOption
以将其连接到
Super
class Super
class Sub extends Super

class Covariant[+A]
class Contravariant[-A]

This gives us the following relationships:
Sub <: Super
Covariant[Sub] <: Covariant[Super]
Contravariant[Super] <: Covariant[Sub]