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]