泛型类型参数的多重上界
在Kotlin中,我有一个接口和一个类。比如,接口A 和类B。
我想写一个带泛型的函数或类,使其泛型参数表示所有同时是A 和B 的子类型。怎么实现呢?
当我写 <T: A, B> 时,B被认为是第二个泛型,而不是T 的超类型。
下面是一段示例代码:
interface A
open class B
class C: B(), A
class D: B(), A
class E: B()
class F: A
fun <T: A> foo(x: T) {} // How to write generic here?
fun bar() {
val c = C()
val d = D()
val e = E()
val f = F()
foo(c) // This should be available
foo(d) // This should be available
foo(e) // This should throw error
foo(f) // This should throw error
}
我可以像下面这样引入另一个类型 P,并在 foo 中使用它:
open class P: B(), A
fun <T: P> foo(x: T) {}
但这将需要我把 C 和 D 的声明改成如下:
class C: P()
class D: P()
我在实际项目中有很多这样的类,而且不想让作用域里再多出额外的类型来,因此我宁愿不走这条路。有没有更好的替代方案?
解决方案
这正是关键字 where 发挥作用的地方:
fun <T> foo(x: T)
where T : A,
T : B {
}
现在 x 的类型必须同时是 A 和 B。编译器不仅会在 foo(e) 处报错,而且正如要求的那样,在 foo(f) 处也会报错:
参数类型不匹配:实际类型是 'F',但期望的类型为 'A & B'。
A & B 是一个 交叉类型,这是你不能显式声明的东西(因此也不会有 val x: A & B)。它只能被推断,但Kotlin能在幕后处理它,保持类型安全与类型推断按预期工作。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。