Kotlin中泛型的协变

news/2024/11/19 18:42:51/
kotlin">interface Shapeclass Circle : Shapefun main() {val shapes1: List<Shape> = listOf<Circle>()val shapes2: MutableList<Shape> = mutableListOf<Circle>()
}

如上代码,第一行赋值语句是OK的,第二行赋值语句在编辑器上直接就报错了。为什么会这样,这需要理解协变概念。

只读集合类型是协变的,相反,可变集合不是协变的。

协变协变有什么用?

协变的话,父类型就可以接收子类型,比如:

kotlin">val shapes1: List<Shape> = listOf<Circle>()

如上代码,List是一个协变类型,所以泛型Shape可以接收Circle,这是没问题的,因为List是只读的,那么List中的元素就只可能是Circle类型,不会发生改变。

而非协变的话父类型就不能接收子类型,如下:

kotlin">val shapes2: MutableList<Shape> = mutableListOf<Circle>()

如上代码,在编辑器中是直接报错的,因为MutableList不是只读的,它可以增、删除 、改,比如shapes2.add(Retangel()),但我们的集合实际是想只保存Circle的,它会导致异常,示例如下:

kotlin">interface Shapeclass Circle : Shape
class Rectangle: Shapefun main() {val circles: MutableList<Circle> = mutableListOf()val shapes: MutableList<Shape> = circlesshapes.add(Rectangle())val circle: Circle = circles[0] // 其实它是一个Rectangle
}

如上代码,如果非协变类型可以子类给父类,这将导致异常,所以在编辑器中这种赋值时会直接报错。

另外,协变和非协变,是看左边的类型,如下代码:

kotlin">val shapes1: List<Shape> = listOf<Circle>()
val shapes2: List<Shape> = mutableListOf<Circle>()

如上代码,左边的类型是List,这是只读类型,所以它是协变的,那么它就能接收子类型的集合,不管这个子类型是List还是MutableList都可以。

如果不是协议的,则不能接收子类型,不管子类型是List还是MutableList都不可以。示例如下:

kotlin">val shapes1: MutableList<Shape> = listOf<Circle>()
val shapes2: MutableList<Shape> = mutableListOf<Circle>()

如上代码,左边的类型是MutableList,不是只读的,所以它不是协变的,所以不能接收子类型,不管子类型是List还是MutableList都不可以。


http://www.ppmy.cn/news/1548294.html

相关文章

大语言模型提示词工程学习--写小说系列(文心一言豆包通义千问):目录

前言 我本身是从事软件开发行业&#xff0c;对计算机类的东西感兴趣&#xff0c;随着ChatGPT的爆发&#xff0c;国内大厂也纷纷推出自己的大语言模型&#xff0c;大语言模型已经逐渐进入到普通人的日常生活当中&#xff0c;为了更好的学习提示词技巧&#xff0c;通过写一篇有质…

使用 Keras 训练一个卷积神经网络(CNN)(入门篇)

在上一篇文章中&#xff0c;我们介绍了如何使用 Keras 训练一个简单的全连接神经网络&#xff08;MLP&#xff09;。本文将带你深入学习如何使用 Keras 构建和训练一个卷积神经网络&#xff08;CNN&#xff09;&#xff0c;用于图像分类任务。我们将继续使用 MNIST 数据集&…

linux alsa-lib snd_pcm_open函数源码分析(四)

欢迎直接到博客 linux alsa-lib snd_pcm_open函数源码分析&#xff08;四) 系列文章其他部分: linux alsa-lib snd_pcm_open函数源码分析&#xff08;一) linux alsa-lib snd_pcm_open函数源码分析&#xff08;二) linux alsa-lib snd_pcm_open函数源码分析&#xff08;三)…

CSS响应式布局实现1920屏幕1rem等于100px

代码解析与实现 设置根元素的 font-size 为 5.208333vw 假设你想让根元素的 font-size 基于视口宽度来动态调整。我们可以通过设置 font-size 为 5.208333vw 来让 1rem 相当于视口宽度的 5.208333%。 计算 5.208333vw: 当屏幕宽度为 1920px 时&#xff0c;5.208333vw 等于 5…

后端返回大数问题

这个问题并不难,但是在开发的时候没有注意到 后端返回了一个列表数据,包含id,这个id是一个大数,列表进入详情,需要将id传入到详情页面详情页面内部通过id获取数据一直404,id不正确找问题,从路由传参到请求数据发现id没有问题,然后和后端进行联调,发现后端返回的id和我获取的id…

django从入门到精通(五)——表单与模型

好的&#xff0c;下面将详细介绍 Django 的表单与模型&#xff0c;包括它们的定义、使用、如何在 Django Admin 中结合使用&#xff0c;以及相关的字段类型和验证机制。 Django 模型与表单 1. Django 模型 Django 模型是一个 Python 类&#xff0c;用于定义数据库中的数据结…

【ACM出版】第四届信号处理与通信技术国际学术会议(SPCT 2024)

& 第四届信号处理与通信技术国际学术会议&#xff08;SPCT 2024&#xff09; 2024 4th International Conference on Signal Processing and Communication Technology 2024年12月27-29日 中国深圳 www.icspct.com 第四届信号处理与通信技术国际学术会议&#x…

Python 正则表达式进阶用法:字符集与字符范围详解

Python 正则表达式进阶用法&#xff1a;字符集与字符范围详解 正则表达式是文本处理和数据清洗中不可或缺的工具。在前面的学习中&#xff0c;我们已经了解了基本的正则表达式匹配&#xff0c;如匹配单个字符、字符串开始和结束的位置等。今天&#xff0c;我们将进入正则表达式…