我试图了解何时在泛型中使用“in”关键字而不是“out”关键字(允许分配子类)。
如果重要的话,我实际上是关注tutorial。
让我们说我们有以下课程定义:
class ParameterizedConsumer<in T> {
fun toString(value: T): String {
return value.toString()
}
}
这是如何编译的,因为值不能保证是String?这是关键字的作用吗?它告诉班级有保证类型不会是任何其他子类?我只是不清楚它的用例,你能帮忙吗?
教程说我将能够调用以下内容,但我对它的变化感到迷茫:
val parameterizedConsumer = ParameterizedConsumer<Number>()
val ref: ParameterizedConsumer<Double> = parameterizedConsumer
assertTrue(ref is ParameterizedConsumer<Double>)
更新:我现在明白了。 Out意味着你可以在制作时垂头丧气。和“在”意味着你可以在分配时贬低。
所以在java中这是不允许的:
// Java
void demo(Source<String> strs) {
Source<Object> objects = strs; // !!! Not allowed in Java
// ...
}
但是在kotlin我们可以解决这个问题,如果我们使用“out”关键字,我们可以将其分配给一个下层类(子类)。同样使用“in”我们可以在内部将一个子类传递给类,但不能向外传递。
答案 0 :(得分:3)
它告诉类有一个保证类型不会是任何其他子类?我只是不清楚它的用例,你能帮忙吗?
假设您有一个功能想要将一些项目添加到您提供的列表中。这些项目的类型为Int
。
问题:此功能可接受哪种列表?
答案:MutableList<Int>
,MutableList<Number>
,MutableList<Any>
。或者,简而言之,MutableList<in Int>
。
本着同样的精神,让我们来解释out
投影。
假设您有一个想要从您提供的列表中获取某些元素的函数。这些项目的类型为Future
。
问题:此功能可接受哪种列表?
答案:List<Future>
,List<RunnableFuture>
,List<ScheduledFuture>
...或者,简而言之,List<out Future>
。
答案 1 :(得分:1)
我会回答你的部分问题
这是如何编译的,因为值不能保证为String
那又怎样?您可以在任何类型上致电.toString()
。这就是你得到一个你将要回来的字符串的方式。