我想在其类型参数中使用以下特征逆变。
asm(
"ldr r0, [r1, %[my_offset]] \n" : : [my_offset]"i" (offsetof(MyStruct, a))
);
上述解决方案的问题在于Scala标准库trait Preferences[-A] {
def ordering: Ordering[A]
}
在其类型参数中是不变的。这篇SO帖子讨论了为什么会出现这种情况。
我已经为我的问题开发了两种解决方案。第一种解决方案是使参数Ordering
和上限。
A
第二种是使用trait Preferences[-A] {
def ordering[B <: A]: Ordering[B]
}
。
implicit
这两个都编译,但我不理解权衡。这些方法中的一种更普遍吗?我应该使用第三种方法吗?
答案 0 :(得分:3)
在尝试解决您遇到的问题时,您的第一个解决方案被认为是最佳做法(具有逆变参数作为方法或函数的返回类型)。
第二个解决方案称为通用类型约束,当您想要推断出正确的类型而不让编译器“适合它们”时,它们非常有用。例如,如果你有
def foo[A, B <: A](a: A, b: B): Whatever = ???
并且您尝试将其作为
调用foo(42, "something")
编译器会将A
推断为Any
,因为这样整个事情就适合了;类型B
,String
,确实是Any
的子类型。有了GTC:
def foo[A, B](a: A, b: B)(implicit ev: B <:< A)
编译器会将您的参数分别推断为Int
和String
。只有在那之后它才会检查GTC,并且这里不会进行扩展,因为已经推断出参数类型。因此编译将失败,因为String不是Int。
只要你明确定义你的A和B,并且你总是会(因为没有什么可以推断它们),你的第一个解决方案就好了。不需要暗示。