10 | 泛型:逆变or协变,傻傻分不清?
- 深入了解
- 翻译
- 解释
- 总结
Kotlin泛型是软件开发中重要的概念。本文通过生动的例子和清晰的解释,帮助读者快速了解Kotlin泛型的基础知识和应用场景。文章首先介绍了泛型基础部分,通过遥控器类的例子说明了泛型的作用,以及如何使用泛型来实现代码逻辑的复用。接着讨论了泛型的不变性问题,并介绍了逆变和协变的概念。通过具体的代码示例和生活场景,读者可以更直观地理解泛型的应用和型变的概念。在逆变部分,作者以遥控器和电视机的关系为例,说明了逆变的概念及解决方法。在协变部分,以点外卖的场景为例,介绍了协变的概念及解决方法。最后,提到了Java和Kotlin的型变语法对比,强调了Kotlin相对简洁的语法。另外,文章还介绍了Kotlin中的“星投影”概念,以及在不确定泛型实参类型时的应用场景和解决方法。通过这些内容,读者可以快速了解Kotlin泛型的基本概念和高级特性,为进一步深入学习和实践打下良好的基础。文章通过生动的例子和清晰的解释,帮助读者快速了解Kotlin泛型的基础知识和应用场景。
《朱涛 · Kotlin 编程第一课》,新⼈⾸单¥59
全部留言(32)
- 最新
- 精选
- 白乾涛我觉得Java的 <? extends T> <? super Object> 语法不抽象呀,相比 kotlin 中的 in out 反而更清晰
作者回复: 也许是角度不一样。这里,我觉得抽象的原因是这样的:Kotlin的in out,我一下就能反应过来,in是参数,out是返回值。但<? extends T> <? super Object>就会让我有点懵,不知道哪个该用在什么地方。
2022-01-20419 - A Lonely CatJava中的协变:<? extends T> Java中的逆变:<? super Object> Java中的“星投影”:<?>
作者回复: 感谢这位同学的补充~
2022-01-19214 - $Kotlin声明处型变无法支持又有in又有out,只能在使用处根据情况型变。
作者回复: 赞~
2022-01-19212 - 白乾涛协变:<? extends T> out-作为返回值-可以读取,不可以写入 逆变:<? super T> in-作为参数-可以写入,不可以读取(只能以Object读取)
作者回复: 很好的总结,赞~
2022-02-0939 - 白乾涛老师,文稿中说下面的代码会报错,实际上并不会报错呀 open class Animal() class Dog : Animal() class Cat : Animal() fun foo(list: MutableList<Animal>) { list.add(Dog()) val animal: Animal = list[0] } fun main() { foo(mutableListOf(Cat())) // 需要父类集合,传入子类集合 }
作者回复: 嗯……确实,编译器把子类又推导成父类集合了。这里应该限定泛型实参的:mutableListOf<Cat>(Cat()) 感谢纠正~
2022-02-094 - neo从型变的父子关系来分类的话,分为逆变和协变 泛型作为参数,用 in;泛型作为返回值,用 out 这两个条规则有冲突的时候应该怎么办呢
作者回复: 符合条件的话,可以用:@UnsafeVariance。如果泛型真的同时存在读取和写入的话,那么就属于泛型不变性的范畴了,也就是说,它无法支持逆变和协变。
2022-04-182 - Paul Shan使用处的型变,可以使用星投影,更灵活,但是范围比较小。声明处的型变,解决的是泛型类本身的约束,一次定义,所有使用的地方都受到相应影响,星投影处也不例外,使用处不得修改。个人觉得优先使用声明处的型变,使用处的型变会导致不同的使用处,型变不同的情况,带来额外的复杂性。星投影我在实际中基本没用过,老师能否举一个实际中用星投影能很好解决问题的场景。
作者回复: 使用处,声明处的总结很棒!星投影的使用场景,往往是我们不需要范型的时候。
2022-03-191 - Renext打卡
作者回复: 加油~
2022-01-241 - 阶前听雨很赞,基本能分清了,再多看几遍以加深理解。
作者回复: 泛型确实比较抽象,要多体会,加油哈~
2022-01-231 - louc历史上最好的讲泛型,通俗易懂
作者回复: 看到你的回复我真的很高兴,希望你继续坚持学习下去~
2022-04-30