考虑以下层次结构:
class C1
class C2 extends C1
class C3 extends C2
class C4 extends C3
我想写一个只接受类型的函数C2
and C3
。为此我想到了以下几点:
def f [C >: C3 <: C2](c :C) = 0
我期望以下行为
f(new C1) //doesn't compile, ok
f(new C2) //compiles, ok
f(new C3) //compiles, ok
f(new C4) // !!! Compiles, and it shouldn't
问题是当调用它时C4
,我不想允许,但编译器接受。我明白那个C4 <: C2
是正确的C4
可以看作是C3
。但是当指定边界时[C >: C3 <: C2]
,我希望编译器找到一个C
同时尊重两个界限,而不是一一尊重。
问题是:有没有办法实现我想要的,如果没有,编译器是否试图避免与此不一致?
Edit: 从答案中我意识到我的假设是错误的。C4
总是满足C >: C3
,所以这两个界限确实受到尊重。我的用例的方法是C3 <:< C
.
静态地讲,是的。施加这个约束非常简单:
def f[C <: C2](c: C)(implicit ev: C3 <:< C) = 0
f(new C4)
现在无法编译。
问题是,可能无法在编译时禁止以下行为:
val c: C3 = new C4
f(c)
这里变量c
具有静态类型C3
,它通过了编译器的任何类型的类型检查,但它实际上是一个C4
在运行时。
在运行时,您当然可以使用反射或多态性检查类型并抛出错误或返回Failure(...)
or None
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)