目录

  • 1. 泛型
  • 2. 通配符(上下界)
  • 3. 泛型函数
  • 4. 泛型约束

本小结介绍的是kotlin的泛型,先从Java的泛型开始介绍:

1. 泛型

kotlin中使用泛型的方式跟Java相差不大:

class Box<T>(t: T) {var value = t
}// 使用
val box: Box<Int> = Box<Int>(1)
//kotlin可以自动推断类型
val box2 = Box(1)

2. 通配符(上下界)

Java

Java中,在没有通配符上下界的情况下,是不可变的,也就是说,在指定泛型类型后,Java就能在编译期确定泛型的类型,防止运行时出现异常。为了泛型的灵活性,提出了通配符上下界。

  1. 通配符上界,只能从中读取元素,不能添加元素,称为生产者(Producers),用<? extends T>表示。
List<String> strs = new ArrayList<String>();
strs.add("0");
strs.add("1");
List<? extends Object> objs = strs;
objs.get(0); // 可以获取
objs.add(1); // 错误,不能添加

之所以不能添加元素的原因很明显,因为没法确定添加的实例类型跟定义的类型是否匹配。

  1. 通配符下界,只能添加元素,不能直接读取下界类型的元素,称为消费者(Consumers),用<? super T>表示。
List<String> strs = new ArrayList<String>();
strs.add("0");
strs.add("1");
List<? super String> objs = strs;
objs.add("1");
objs.set(0, "2");
//String s = objs.get(0); get不能直接得到String类型的对象
Object s = objs.get(0);

不得不说,这样做法是合理的,但是是可能会出错的。来看看Kotlin是怎么实现类似的情况的。

kotlin

在Kotlin中,使用声明位置变异来解决这种问题:

  1. 使用out关键字标识的泛型T,只能作为返回值,而不能作为传入参数。
abstract class Source<out T> {// 使用out的话,T只能作为返回值abstract fun nextT(): T// 不能作为传入参数,下面会报错// abstract fun add(value: T)
}fun demo(strs: Source<String>) {val objects: Source<Any> = strs
}

这种做法实际上就是对应Java中的<? extends T>,因为只能作为返回值而不能作为参数,所以不会出现Java可能出现的运行异常。

  1. 使用in关键字标识的泛型T,只能作传入参数,而不能作为返回值。
abstract class Source<in T> {// 使用in的话,只能作为传入参数,不能作为返回值// abstract fun nextT(): Tabstract fun add(value: T)
}fun demo(strs: Source<Number>) {val objects: Source<Double> = strs // Double是Number的子类型
}

这样是不是更加合理了呢? 用一句概括Kotlin的这种做法,就是:

Consumer in, Producer out!

3. 泛型函数

Kotlin同样支持泛型函数:

fun <T> singletonList(item: T): List<T> {
}fun <T> T.basicToString() : String {  // extension function
}

使用的时候,在函数名称后面指定具体的类型参数:
val l = singletonList<Int>(1)

4. 泛型约束

Kotlin的泛型约束和类的继承一样,使用:代替extends对泛型的的类型上界进行约束:

class SwipeRefreshableView<T : View>{}

同时Kotlin支持多个类型的上界约束,,使用where关键字:

class SwipeRefreshableView<T>where T : View,T : Refreshable {
}

kotlin学习之泛型(十四)相关推荐

  1. Kotlin 学习笔记(十四)浅读协程

    上一篇-Kotlin 学习笔记(十三)高阶函数 为什么需要协程   举例一个异步编程中最常见的场景:后台线程执行一个A任务,下一个B任务依赖于A任务的执行结果,所以必须等待上一个任务执行完成后才能开始 ...

  2. Spring Security技术栈学习笔记(十四)使用Spring Social集成QQ登录验证方式

    上一篇文章<Spring Security技术栈开发企业级认证与授权(十三)Spring Social集成第三方登录验证开发流程介绍>主要是介绍了OAuth2协议的基本内容以及Spring ...

  3. 虚拟内存——Windows核心编程学习手札之十四

    虚拟内存 --Windows核心编程学习手札之十四 系统信息 有些操作系统的值是根据主机而定的,如页面大小.分配粒度大小等,这些值不用硬编码形式,进程初始化时应检索这些值以使用.函数GetSystem ...

  4. Windows保护模式学习笔记(十四)—— 阶段测试

    Windows保护模式学习笔记(十四)-- 阶段测试 题目一 解题步骤 题目二 解题步骤 题目一 描述:给定一个线性地址,和长度,读取内容 int ReadMemory(OUT BYTE* buffe ...

  5. OpenCV学习笔记(十四):重映射:remap( )

    OpenCV学习笔记(十四):重映射:remap( ) 图像的坐标映射是通过原图像与目标图像之间建立一种映射关系,这种映射关系有两种,一种是计算原图像任意像素在映射后图像的坐标位置,另一种是计算变换后 ...

  6. QT学习笔记(十四):QLayout的属性介绍

    QT学习笔记(十四):QLayout的属性介绍 主要包括QBoxLayout.和QGridLayout以及QFormLayout等的参数类似. 我主要说明一下QGridLayout在QtDesigne ...

  7. MATLAB学习笔记(十四)

    MATLAB学习笔记(十四) 一.线性方程组求解 1.1 直接法 1.1.1 利用左除运算符 1.1.2 利用矩阵分解 1.2 迭代法 1.2.1 雅可比(Jacobi)迭代法 1.2.2 高斯-赛德 ...

  8. python数据挖掘学习笔记】十四.Scipy调用curve_fit实现曲线拟合

    #2018-03-28 10:02:08 March Wednesday the 13 week, the 087 day SZ SSMR python数据挖掘学习笔记]十四.Scipy调用curve ...

  9. JavaScript学习(八十四)—变量

    JavaScript学习(八十四)-变量 一.什么是变量? 白话: 变量就是一个装东西的盒子 通俗:变量是用于存放数据的容器. 我们通过 变量名 获取数据,甚至数据可以修改. 二.变量在内存中的存储 ...

  10. JavaScript学习(七十四)—递归函数

    JavaScript学习(七十四)-递归函数 一.什么是递归? 如果一个函数可以在内部调用其本身,那么这个函数就是递归函数,简单地说,函数内部自己调用自己,这个函数就是递归函数 由于递归很容易发生&q ...

最新文章

  1. 第一次接觸sbt會遇到的
  2. SSH框架执行自己定义的SQL语句
  3. 简单易用且功能丰富的纯Swift下载框架
  4. expdp / impdp 用法详解(Oracle)
  5. 内功重修之数据结构----数组
  6. 在vc++里面进行图像处理的时候应该把图形放哪_PCB抄板抄板,到底应该怎么抄?...
  7. 《从0到1学习Flink》—— Apache Flink 介绍
  8. leetcode —— 1282. 用户分组
  9. java 存储过程返回结果集_通过SQL“select * from”从java存储过程返回结果集
  10. jQuery操作动画队列
  11. 外设适配-TI954 记录
  12. Freeswitch 录制视频并播放
  13. python谷歌翻译 频率限制_利用Google进行无长度限制的文本翻译(无需API,无需Money)...
  14. 计算机审计风险未来发展,浅谈计算机审计风险的研究
  15. Windows异常学习笔记(三)—— VEHSEH
  16. 使用dos删除隐藏的.git文件
  17. 游戏3D建模入门,有哪些建模软件可以选择?
  18. jlinkV8指示灯不亮 usb无法识别的问题
  19. 中国历史上的三次衣冠南渡
  20. Windows怎么让防火墙开放端口

热门文章

  1. Lua 和 C 交互中虚拟栈的操作和遍历
  2. CreateProcess启动游戏注入DLL
  3. OD+IDA6.1破解HideWizardv9.29(无忧隐藏)
  4. python网络编程实例简析
  5. Sql Server事务日志
  6. 多线程小抄集(新编二)
  7. Kafka解析之topic创建(2)
  8. 曹大带我学 Go(8)—— 一个打点引发的事故
  9. Go pprof 快速分析 CPU 高负载问题
  10. 【大会】AI能解决哪些问题?