解析Kotlin中的Unit【笔记摘要】

1. Kotlin的Unit 和 Java的void 的区别

// Java
public void sayHello() {
  System.out.println("Hello!")
}

// Kotlin
fun sayHello(): Unit {
  println("Hello!")
}

Unit 和 Java 的 void 真正的区别在于,void 是真的表示什么都不返回,而 Kotlin 的 Unit 却是一个真实存在的类型:

//Unit的源码,这表明它是一个object单例类
public object Unit {
    override fun toString() = "kotlin.Unit"
}

2. 省略Unit,Kotlin会自动补上

一个完整的”无返回值“的函数写法如下,即返回类型为Unit,函数最后return Unit

fun sayHello() : Unit {
  println("Hello!")
  return Unit
}

当函数返回类型是Unit时,我们是可以省略掉函数的返回类型的,因为 Kotlin 也会帮我们自动加上

fun sayHello() {
  println("Hello!")
  return Unit
}

return 我们一样可以省略不写,Kotlin 也会帮我们自动加上

fun sayHello() : Unit {
    println("Hello!")
}

这两个 Unit 是不一样的,上面的是 Unit 这个类型,下面的是 Unit 这个单例对象。这个并不是 Kotlin 给 Unit 的特权,而是 object 本来就有的语法特性
包括你也可以这样写:

val unit: Unit = Unit

因此全都省略的情况,实际上就是返回类型为Unit,并且最后一行返回了Unit这个单例对象

fun sayHello() {
  println("Hello!")
}

3. Unit总结

所以在结构上,Unit 并没有任何的特别之处,它就只是一个 Kotlin 的 object 而已。
它的特殊之处,更多的是在于语义和用途的角度:它是个由官方规定出来的、用于「什么也不返回」的场景的返回值类型。但这只是它被规定的用法而已,而本质上它真就是个实实在在的类型
也就是在 Kotlin 里,并不存在真正没有返回值的函数,所有「没有返回值」的函数实质上的返回值类型都是 Unit,而返回值也都是 Unit 这个单例对象,这是 Unit 和 Java 的 void 在本质上的不同。

4. Unit 的价值所在

意义就在于,Unit 去掉了无返回值的函数的特殊性,消除了有返回值和无返回值的函数的本质区别,这样很多事做起来就会更简单了。
比如在 Java 里面,由于 void 并不是一种真正的类型,所以任何有返回值的方法在子类里的重写方法也都必须有返回值,而不能写成 void,不管你用不用泛型都是一样的:

public abstract class Maker {
  public abstract Object make();
}

public class AppleMaker extends Maker {
  // 合法
  @Override
  public Apple make() {
    return new Apple();
  }
}

public class NewWorldMaker extends Maker {
  // 非法
  @Override
  public void make() {
    world.refresh();
  }
}

泛型:

public abstract class Maker<T> {
  public abstract T make();
}

public class AppleMaker extends Maker<Apple> {
  // 合法
  Override
  public Apple make() {
    return new Apple();
  }
}

public class NewWorldMaker extends Maker<void> {
  // 非法
  Override
  public void make() {
    world.refresh();
  }
}

你只能去写一行 return null 来手动实现接近于「什么都不返回」的效果:

public class NewWorldMaker extends Maker {
  @Override
  public Object make() {
    world.refresh();
    return null;
  }
}

而且如果你用的是泛型,可能还需要用一个专门的虚假类型来让效果达到完美:

public class NewWorldMaker extends Maker<Void> {
  @Override
  public Void make() {
    world.refresh();
    return null;
  }
}

而在 Kotlin 里,Unit 是一种真实存在的类型,所以直接写就行了(这里还借助了Kotlin自动补上Unit类型 和 最后一行自动返回Unit单例对象):

abstract class Maker {
  abstract fun make(): Any
}

class AppleMaker : Maker() {
  override fun make(): Apple {
    return Apple()
  }
}

class NewWorldMaker : Maker() {
  override fun make() {
    world.refresh()
  }
}

泛型:

abstract class Maker<T> {
  abstract fun make(): T
}

class AppleMaker : Maker<Apple>() {
  override fun make(): Apple {
    return Apple()
  }
}

class NewWorldMaker : Maker<Unit>() {
  override fun make() {
    world.refresh()
  }
}

这就是 Unit 的去特殊性,或者说通用性所给我们带来的便利。

5. 延伸:当做纯粹的单例对象来使用

所以如果你什么时候想「随便拿个对象过来」,或者「随便拿个单例对象过来」,也可以使用 Unit,它和你自己创建一个 object 然后去使用,效果是一样的。


参考文章:
Unit 为啥还能当函数参数?面向实用的 Kotlin Unit 详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/768866.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

日期和时区

日期 时区 修改时区可分为两步 删除系统自带的 localtime 文件 rm -f /etc/localtime 将系统中内置的 Shanghai 文件软连接到 /etc/localtime中 sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

Unity3D中,AI角色Rigidbody旋转导致的动画问题

在制作一些AI角色的时候&#xff0c;可能会运用到Rigidbody组件来使AI角色拥有一些相关的物理属性&#xff0c;但是AI角色在受到一些物理碰撞或者惯性等原因&#xff0c;会发生旋转导致动画出现意料外的错误&#xff0c;比如在由动转静的时候&#xff0c;可能会发生向前翻转等一…

TP8/6 子域名绑定应用

原www.xxx.com/admin改为admincms.xxx.com config/app.php

【Linux】线程——线程的概念、线程的特点、线程的优点和缺点、线程和进程、线程函数的使用

文章目录 Linux线程1. 线程的概念1.1 什么是线程 2. 线程的特点2.1 线程的优点2.2 线程的缺点2.4 线程和进程 3. 线程函数的使用pthread_create() 创建线程pthread_self() 获取线程IDpthread_exit() 线程终止pthread_cancel() 线程取消pthread_join() 线程等待pthread_detach()…

Element-UI - el-table中自定义图片悬浮弹框 - 位置优化

该篇为前一篇“Element-UI - 解决el-table中图片悬浮被遮挡问题”的优化升级部分&#xff0c;解决当图片位于页面底部时&#xff0c;显示不全问题优化。 Vue.directive钩子函数已在上一篇中详细介绍&#xff0c;不清楚的朋友可以翻看上一篇&#xff0c; “Element-UI - 解决el-…

3.js - 色调映射(renderer.toneMapping)

// ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import * as TWEEN…

不同操作系统下的换行符

1. 关键字2. 换行符的比较3. ASCII码4. 修改换行符 4.1. VSCode 5. 参考文档 1. 关键字 CR LF CRLF 换行符 2. 换行符的比较 英文全称英文缩写中文含义转义字符ASCII码值操作系统Carriage ReturnCR回车\r13MacIntosh&#xff08;早期的Mac&#xff09;LinefeedLF换行/新行\…

Windows下载安装配置并使用Redis(保姆级教程)

文章目录 1、Redis的下载与安装 2、Redis的使用 3、Redis的图形界面客户端 4、Redis开机自启动 1、Redis的下载与安装 下载Redis&#xff1a;https://pan.baidu.com/s/1zBonkO2y6AZeqCdRe0W5ow?pwd9999 提取码: 9999 下载后直接解压就可以使用了 2、Redis的使用 我们…

全网最佳硕士研究生复试简历模板

硕士研究生复试简历模板 ✨ 简介 提供了一个适用于国内硕士研究生复试的个人简历模板。该模板通过统一的“样式”形成规范的Word格式&#xff0c;是目前研究生复试的最佳简历模板之一。模板使用“华文中宋”字体&#xff0c;如您的电脑中未安装此字体&#xff0c;请提前安装。…

软件测试与质量保证 | 云班课选择题库

目录 第1章课后习题 第2章课后习题 第3章课后习题 第4章课后习题 第5章课后习题 第6章课后习题 第7章课后习题 第8章课后习题 第9章课后习题 第10章课后习题 第11章课后习题 第12章课后习题 第13章 测试相关未分类习题 第1章课后习题 1. 与质量相关的概念包括 &a…

去中心化革命:探索区块链技术的前沿

随着信息技术的飞速发展&#xff0c;区块链技术作为一种新兴的去中心化解决方案&#xff0c;正逐渐改变着我们的经济、社会和技术格局。本文将从区块链的基本原理、当前的应用实例以及未来的发展趋势三个方面&#xff0c;深入探讨区块链技术在革命性变革中的角色和影响。 1. 区…

springboot 自定义的全局捕获异常失效

背景&#xff1a;springbootspringcloud 分布式微服务。 问题&#xff1a;公共模块在使用RestControllerAdvice全局捕获异常时&#xff0c;捕获不到子服务抛出的相应异常 首先看一下全局异常组件有么有被扫描到 如何查看&#xff0c;很简单只需要写一段类加载打印代码&#x…

【hot100】跟着小王一起刷leetcode -- 739. 每日温度

【hot100】跟着小王一起刷leetcode -- 739. 每日温度 739. 每日温度题目解读思路 代码总结 739. 每日温度 题目解读 739. 每日温度 老规矩&#xff0c;咱先看下题目。总结下来就是&#xff0c;你要返回一个answer数组&#xff0c;answer[i]中存储的应该是temperatures数组中…

Android跨进程通信,binder传输数据过大导致客户端APP,Crash,异常捕获,监听异常的数值临界值,提前Hook拦截。

文章目录 Android跨进程通信&#xff0c;binder传输数据过大导致Crash&#xff0c;异常捕获&#xff0c;监听异常的数值临界值&#xff0c;提前Hook拦截。1.binder在做跨进程传输时&#xff0c;最大可以携带多少数据1.1有时候这个1m的崩溃系统捕获不到异常&#xff0c; 2.监测异…

深度学习与飞桨 PaddlePaddle Fluid

编辑推荐 飞桨PaddlePaddle是百度推出的深度学习框架&#xff0c;不仅支撑了百度公司的很多业务和应用&#xff0c;而且随着其开源过程的推进&#xff0c;在其他行业得到普及和应用。 本书基于2019年7月4日发布的飞桨PaddlePaddle Fluid 1.5版本&#xff08;后续版本会兼容旧版…

[工业网络] 模型建立

普渡大学ICS参考模型 普渡企业参考架构&#xff08;PERA&#xff09;是由西奥多J威廉姆斯&#xff08;Theodore J. Williams&#xff09;和普渡大学计算机集成制造工业大学联盟的成员在1990年代开发的企业架构参考模型。该模型被ISA-99&#xff08;现为ISA/IEC 62443&#xff…

warning: LF will be replaced by CRLF the next time Git touches it warning

问题&#xff1a; warning: in the working copy of , LF will be replaced by CRLF the next time Git touches it warning: 今天上传git时报错&#xff0c;使用Ai&#xff1b;得知&#xff1b; 解决&#xff1a; 将 Git 配置为不自动转换换行符&#xff0c;使用以下命令…

snap和apt的区别简单了解

Linux中没有tree命令的时候提示安装的时候出现了两个命令&#xff0c;简单看了看两者有何区别&#xff08;一般用apt就可以了&#xff09;&#xff1a; sudo snap install tree 和 sudo apt install tree 这两个命令都是用来安装 tree 命令行工具的&#xff0c;但它们使用的是不…

webSocket网页通信---使用js模拟多页面实时通信

webSocket是什么 WebSocket是一种先进的网络技术&#xff0c;它提供了一种在单个TCP连接上进行全双工通信的能力。传统的基于HTTP的通信是单向的&#xff0c;即客户端发起请求&#xff0c;服务器响应请求&#xff0c;然后连接关闭。但是&#xff0c;WebSocket允许服务器和客户端…

Spring Boot2.x教程:(四)Spring Boot2.6及之后版本整合Knife4j的问题

Spring Boot2.6及之后版本整合Knife4j的问题 1、概述2、问题出现原因及解决办法3、拓展3.1、为什么发生这种变化 4、总结 大家好&#xff0c;我是欧阳方超&#xff0c;可以扫描下方二维码关注我的公众号“欧阳方超”&#xff0c;后续内容将在公众号首发。 1、概述 今天在2.7…