与Kotlin泛型混淆

我是Kotlin的新手,我正在尝试编写一些相当简单的代码,但我无法弄清楚如何使用泛型来实现它。

我有一个Handler特点,代表事物的处理程序。 我不能更改处理程序的代码,因为它来自库

 trait Handler<T> { fun handle(result: T) } 

下面的所有代码都在我的控制之下 –

User是具有诸如AdminUserGuestUser等子类的公开类。

一个名为AdminUserAction的特性可以创建一个AdminUser列表,然后将列表传递给List<AdminUser>一个处理器。

 trait AdminUserAction { fun then(handler: Handler<List<AdminUser>>) } 

现在我想为AdminUserAction传递一个AdminUserAction处理程序,而不是AdminUser 。 假设处理程序只记录用户的名字,并且不对管理员指定的属性做任何事情。

 fun doIt(action: AdminUserAction, printAllNames: Handler<List<User>>) { action.then(printAllNames) } 

但是,这段代码给了我一个TypeMismatch

由于处理程序的类型是List<T>并且是不可变的,所以前面的代码应该是完全安全的,但编译器无法解决这个问题。

如果我可以访问处理程序的代码,我可以做到以下几点,它会工作 –

 trait Handler<in T> { fun handle(result: T) } 

但是,正如我之前所说,我不能修改Handler,因为它来自一个库。 此外,似乎很难做到这一点,因为处理程序的类型是完全一般的,应该也可以用于其他类型的处理程序。

我试过继承Handler并使用它 –

 trait ListHandler<in T>: Handler<List<T>> { } 

但是现在我得到一个错误,说: “参数T被声明为'在',但发生在'不变'的位置在处理程序”

我试过了 –

 trait ListHandler<in T>: Handler<List<in T>> { } 

但是这给了我更多的错误。

为什么这么混乱? 我怎样才能使用泛型来获得前面的代码工作?

编辑:

我可以通过编写一个将Handler<List<User>>转换为Handler<List<AdminUser>>的通用函数来使其工作,

 fun <T: User> fromGeneric(handler: Handler<User>): Handler<T> { return object: Handler<T> { override fun handle(result: List<T>) { handler.handle(result) } } } 

接着 –

 fun doIt(action: AdminUserAction, printAllNames: Handler<List<User>>) { action.then(fromGeneric(printAllNames)) } 

但是,这似乎太浪费了。 特别是从fromGeneric看转换函数的fromGeneric 。 它什么都不做! 然而,我必须经历每次使用它的方式来满足这些类型。

有没有更好的办法? 在技​​术上是否可以使Kotlin编译器更加智能化,从而不需要这种类型的混战?

有几个解决方案:

AdminUserAction的定义更改为

 trait AdminUserAction { fun then(handler: Handler<in List<AdminUser>>) } 

或将AdminUserAction的定义更改为

 trait AdminUserAction { fun then(handler: Handler<List<User>>) } 

或者像这样投出printAllNames

 fun doIt(action: AdminUserAction, printAllNames: Handler<List<User>>) { action.then(printAllNames as Handler<List<AdminUser>>) }