设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间13 现在时间13 缓存数据 到现在一共是295天,有了人生中第一张迷你专辑,我期许自己这不会是句号,只会是个逗号,会一直一直一直突破的,直到我唱不动的那天。

到现在一共是295天,有了人生中第一张迷你专辑,我期许自己这不会是句号,只会是个逗号,会一直一直一直突破的,直到我唱不动的那天。 -- 一种原谅

查看: 347|回复: 0

kotlin中泛型中in和out的区别解析

[复制链接]

  离线 

TA的专栏

  • 打卡等级:无名新人
  • 打卡总天数:2
  • 打卡月天数:0
  • 打卡总奖励:23
  • 最近打卡:2025-01-02 20:21:07
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
31
主题
25
精华
0
金钱
116
积分
60
注册时间
2023-9-30
最后登录
2025-5-31

发表于 2025-5-31 06:50:52 | 显示全部楼层 |阅读模式
1.概念含义


  • in关键字(逆变)

    • 在Kotlin泛型中,
      1. in
      复制代码
      关键字主要用于定义逆变(Contravariance)。它表示一个泛型类型参数可以是指定类型或者它的超类型。
    • 简单来说,就是对于类型
      1. A
      复制代码
      1. B
      复制代码
      ,如果
      1. A
      复制代码
      1. B
      复制代码
      的子类型,那么
      1. Consumer<B>
      复制代码
      1. Consumer<A>
      复制代码
      的子类型。这里的
      1. Consumer
      复制代码
      是一个具有
      1. in
      复制代码
      关键字修饰泛型参数的类型,例如接口或者类。

  • out关键字(协变)

      1. out
      复制代码
      关键字用于定义协变(Covariance)。它意味着一个泛型类型参数可以是指定类型或者它的子类型。也就是说,对于类型
      1. A
      复制代码
      1. B
      复制代码
      ,如果
      1. A
      复制代码
      1. B
      复制代码
      的子类型,那么
      1. Producer<A>
      复制代码
      1. Producer<B>
      复制代码
      的子类型。这里的
      1. Producer
      复制代码
      是一个带有
      1. out
      复制代码
      关键字修饰泛型参数的类型,像接口或者类。


2.使用场景和位置限制


  • in关键字

    • 主要用于函数参数类型
      1. in
      复制代码
      关键字在泛型类型参数用于函数参数时体现逆变特性。例如,考虑一个函数接口
      1. AnimalHandler<in T>
      复制代码
      ,其中
      1. T
      复制代码
      是用
      1. in
      复制代码
      修饰的泛型参数。

  1. interface AnimalHandler<in T> {    fun handle(animal: T): Unit}
复制代码

  • 假设
    1. Dog
    复制代码
    1. Animal
    复制代码
    的子类型。那么一个
    1. AnimalHandler<Animal>
    复制代码
    类型的变量可以接收一个
    1. AnimalHandler<Dog>
    复制代码
    类型的值,因为
    1. AnimalHandler
    复制代码
    1. in
    复制代码
    位置(函数参数位置)是逆变的。
  1. val animalHandler: AnimalHandler<Animal> = object : AnimalHandler<Dog> {    override fun handle(dog: Dog): Unit {        println("Handling a dog")    }}
复制代码

  • 不能用于返回值类型:如果在应该返回
    1. T
    复制代码
    1. in
    复制代码
    修饰的泛型参数)的地方使用,会导致编译错误。因为
    1. in
    复制代码
    规定这个类型参数主要用于接收超类型的值,而不是返回子类型的值。
  • out关键字

    • 主要用于函数返回值类型
      1. out
      复制代码
      关键字在泛型类型参数用于函数返回值时体现协变特性。例如,有一个接口
      1. Producer<out T>
      复制代码
      ,它用于产生某种类型
      1. T
      复制代码
      的对象。

  1. interface Producer<out T> {    fun produce(): T}
复制代码

  • 假设
    1. String
    复制代码
    1. Any
    复制代码
    的子类型。一个
    1. Producer<String>
    复制代码
    可以被当作
    1. Producer<Any>
    复制代码
    来使用,因为
    1. Producer
    复制代码
    1. out
    复制代码
    位置(函数返回值位置)是协变的。
  1. val producer: Producer<Any> = object : Producer<String> {    override fun produce(): String {        return "Hello"    }}
复制代码
不能用于函数参数类型:如果试图将
  1. out
复制代码
修饰的泛型参数用于函数参数,编译器会报错。因为
  1. out
复制代码
规定这个类型参数主要用于返回子类型的值,而不是接收子类型的值作为参数。

3.目的和效果


  • in关键字的目的和效果

    • 目的是实现更灵活的函数参数类型匹配,特别是在处理超类型和子类型关系时。它允许在一个更通用的类型(超类型)的消费者(如接口方法接收超类型参数)中使用更具体的类型(子类型)的实现。这样可以使代码在处理函数参数时,能够以一种逆变的方式利用类型层次结构,增强代码的通用性和灵活性。

  • out关键字的目的和效果

    • 主要目的是在处理返回值类型时,能够利用协变特性,使得代码更加灵活。通过允许子类型的生产者(如接口方法返回子类型的值)可以被当作更通用类型(超类型)的生产者来使用,方便在不同层次的类型之间进行转换和赋值,同时保证类型安全。这在构建具有多态性的返回值类型的接口和类时非常有用,可以让调用者以更灵活的方式处理返回值。

到此这篇关于kotlin中泛型中in和out的区别的文章就介绍到这了,更多相关kotlin in和out区别内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表