当前位置: 首页 > news >正文

网业制作与网站建设建设工程网上质检备案网站

网业制作与网站建设,建设工程网上质检备案网站,用vs2010做的网站,官方百度app下载安装泛型类型简介 泛型类型提供了一种重用代码的方式&#xff0c;使数据类型可以作为变量使用。这样&#xff0c;我们就能创建可以操作不同类型对象的类、接口和方法&#xff0c;只要这些对象符合类型参数的要求。 在 Kotlin 中&#xff0c;泛型类型用 <T> 关键字定义&#x…

泛型类型简介

泛型类型提供了一种重用代码的方式,使数据类型可以作为变量使用。这样,我们就能创建可以操作不同类型对象的类、接口和方法,只要这些对象符合类型参数的要求。

在 Kotlin 中,泛型类型用 <T> 关键字定义,但 T 可以是任意字母或单词。

在本主题中,我们将深入探讨泛型编程,并介绍类型、子类型和变异性(variance)等概念。这些概念在像 Kotlin 这样的静态类型语言中非常重要,因为类型关系会在编译时检查,它们帮助保证类型安全,同时提供灵活性。


类型与子类型

  • 类型:定义了一组有效的值及其对应的一组适当且一致的操作。

  • 子类型:在层级关系中,子类型继承了超类型的所有特性(有效值和操作),但也可能添加额外的值或操作,或者对值进行限制。换句话说,子类型的每个值都是超类型的值,但反之不成立。
    这种关系通常通过面向对象编程中的继承实现。

举例:

val integer: Int = 1
val number: Number = integer // Int 是 Number 的子类型open class Animal
class Dog : Animal()fun main() {val dog: Dog = Dog()var animal: Animal = dog // Dog 是 Animal 的子类型
}

变异性(Variance)

当我们使用泛型(特别是基于泛型的集合)时,情况会变得复杂。

假设 IntNumber 的子类型,考虑泛型类 Box<T>

  • Box<Int> 是不是 Box<Number> 的子类型?

  • Box<Dog> 是不是 Box<Animal> 的子类型?
    Kotlin 中泛型默认是不变的(invariant),因此这些都不是子类型关系,会导致类型不匹配的错误:

class Box<T>val bd: Box<Animal> = Box<Dog>() // 错误
val bn: Box<Number> = Box<Int>() // 错误

这就是变异性的问题。


变异性的三种形式

  • 不变(Invariant):默认模式。对于两种不同类型 A 和 B,Class<A> 既不是 Class<B> 的子类型,也不是超类型。

  • 协变(Covariant):保留类型子关系方向。若 A 是 B 的子类型,则 Class<A> 也是 Class<B> 的子类型。通常适用于“输出”(只返回值)的位置,Kotlin 用 out 关键字表示。

  • 逆变(Contravariant):类型子关系反转。若 A 是 B 的子类型,则 Class<B>Class<A> 的子类型。通常适用于“输入”(只接收值)的位置,Kotlin 用 in 关键字表示。


不变示例(Invariant)

默认情况下泛型是不变的:

val mutableAnimalsFromDogs: MutableList<Animal> = mutableListOf<Dog>() // 错误
val boxOfAnimalsFromDogs: Box<Animal> = Box<Dog>() // 错误

因为既能读也能写,所以不允许这种类型转换。


协变示例(Covariance)

适用于只读场景,比如 Kotlin 的 List 是协变的:

val dogs: List<Dog> = listOf(Dog(), Dog())
val animals: List<Animal> = dogs // 允许,因为 List 是协变的(定义为 List<out T>)

如果定义自己的泛型类协变:

class Box<out T>val dogBox: Box<Dog> = Box<Dog>()
val animalBox: Box<Animal> = dogBox // 允许,Box 是协变的

注意:用 out 修饰后,只能用 T 作为返回类型,不能作为函数参数类型。


逆变示例(Contravariance)

适用于只写场景,比如比较器 Comparator

interface Comparator<in T> {fun compare(e1: T, e2: T): Int
}val animalComparator: Comparator<Animal> = ...
val dogComparator: Comparator<Dog> = animalComparator // 允许,Comparator 是逆变的

in 修饰后,只能用 T 作为函数参数类型,不能作为返回类型。


使用地点变异(Use-site variance)

通过在使用泛型时添加 outin 来实现变异:

fun copyAnimals(source: MutableList<out Animal>, destination: MutableList<in Animal>) {destination.addAll(source)
}val dogs: MutableList<Dog> = mutableListOf(Dog())
val animals: MutableList<Animal> = mutableListOf()copyAnimals(dogs, animals)

这里 source 是协变的,允许读取;destination 是逆变的,允许写入。


星号投影(Star Projection)

当你不知道具体泛型类型,或者不关心具体类型时,用 * 代替类型参数:

class Box<T>(val item: T)fun printItems(boxes: List<Box<*>>) {for (box in boxes) {println(box.item)}
}

这表示 Box 可以持有任何类型。


总结与注意事项

  • 默认泛型是不变的。

  • 只用作输出(返回值)的类型参数应声明为协变(out)。

  • 只用作输入(函数参数)的类型参数应声明为逆变(in)。

  • inout 的使用限制了类型参数在类中的使用方式,保证类型安全。

  • 错误使用可能导致运行时错误,需谨慎。


复杂示例

open class Animal {fun feed() = println("The animal is fed")
}class Dog : Animal() {fun pet() = println("The dog is petted")
}class Cat : Animal() {fun ignore() = println("The cat ignores you")
}class Box<in T, out R>(private var t: T, private val r: R) {fun put(t: T) {this.t = t}fun take(): R {return r}
}fun main() {val dogBox: Box<Animal, Dog> = Box(Dog(), Dog())dogBox.put(Cat())  // 可以,因为 Cat 是 Animal 的子类型val dog: Dog = dogBox.take()  // 返回 Dogval catBox: Box<Dog, Animal> = Box(Dog(), Cat())// catBox.put(Cat()) // 错误,Cat 不是 Dog 的子类型val animal: Animal = catBox.take()  // 返回 Animal
}
http://www.dtcms.com/a/513698.html

相关文章:

  • 河北seo网站设计凭祥网站建设
  • 高端设计参考网站wordpress标题字体改大
  • 云南网站设计联系方式环球资源网网站特色
  • 网站变灰色代码临海高端营销型网站建设地址
  • 景区旅游网站平台建设wordpress注册弹出502
  • 梓潼县住房和城乡建设局网站聊城高端网站设计建设
  • 做网站用什么格式的图片做网站的一般要多少钱
  • 电子商务网站设计与...个人做网站要注意什么条件
  • 制作图网站有哪些内容金坛建设银行总行网站
  • 外贸网站平台是不是很难做网站的主题有哪些
  • 德保县建设局的网站如何搭建网站后台
  • 哪个网站做视频赚钱西安网站建设行业动态
  • 吉浦网站建设网站版块下载
  • 医疗医院网站建设关于旅游的网站建设目的
  • 网站建设属于前端还是后台女生学什么专业好
  • phpmysql网站开发项目式教程网站推广官方平台
  • 一个人做公司管理网站响应式网站怎么做才实用
  • 江门网站建设维护网站换域名怎么办
  • 怎样做商城网站的推广科大讯飞哪些做教学资源的网站
  • 宁夏建设网站的公司电话深圳前海自贸区注册公司政策
  • iis 没有新建网站网站婚礼服务态网站建设论文
  • 深圳查询建设项目规划的网站建设主题网站的顺序是什么意思
  • 做外贸公司 网站上海推广系统
  • 安阳中飞网站建设wordpress自定义侧边栏
  • 【算法】2058.找出临界点之间的最小和最大距离--通俗讲解
  • 静海网站建设手机网站seo怎么做
  • 开了个网站用年份做名字好吗手机做网站多少钱
  • 泉州建设网站的公司做会计要看什么关注什么网站
  • 上海网站论坛建设广东 网站建设
  • 寿宁建设局网站简单的英文网站源码