Kotlin - “in”关键字 - 用于什么?

时间:2018-01-15 06:49:03

标签: kotlin

我试图了解何时在泛型中使用“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”我们可以在内部将一个子类传递给类,但不能向外传递。

2 个答案:

答案 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()。这就是你得到一个你将要回来的字符串的方式。