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

解析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 {// 合法@Overridepublic Apple make() {return new Apple();}
}public class NewWorldMaker extends Maker {// 非法@Overridepublic void make() {world.refresh();}
}

泛型:

public abstract class Maker<T> {public abstract T make();
}public class AppleMaker extends Maker<Apple> {// 合法Overridepublic Apple make() {return new Apple();}
}public class NewWorldMaker extends Maker<void> {// 非法Overridepublic void make() {world.refresh();}
}

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

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

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

public class NewWorldMaker extends Maker<Void> {@Overridepublic 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 详解

相关文章:

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

1. Kotlin的Unit 和 Java的void 的区别 // Java public void sayHello() {System.out.println("Hello!") }// Kotlin fun sayHello(): Unit {println("Hello!") }Unit 和 Java 的 void 真正的区别在于&#xff0c;void 是真的表示什么都不返回&#xff0c…...

仿论坛项目--初识Spring Boot

1. 技术准备 技术架构 • Spring Boot • Spring、Spring MVC、MyBatis • Redis、Kafka、Elasticsearch • Spring Security、Spring Actuator 开发环境 • 构建工具&#xff1a;Apache Maven • 集成开发工具&#xff1a;IntelliJ IDEA • 数据库&#xff1a;MySQL、Redi…...

Spring boot 更改启动LOGO

在resources目录下创建banner.txt文件&#xff0c;然后编辑对应的图案即可 注释工具 Spring Boot Version: ${spring-boot.version},-.___,---.__ /|\ __,---,___,- \ -.____,- | -.____,- // -., | ~\ /~ | …...

python变成几个小程序

专家系统 需要建立‘capital_data.txt’ 空文件 from tkinter import Tk, simpledialog, messageboxdef read_from_file():with open(capital_data.txt) as file:for line in file:line line.rstrip(\n)country, city line.split(/)the_world[country] citydef write_to_fi…...

nginx配置stream代理

项目中遇到某些服务在内网&#xff0c;需要外网访问的情况&#xff0c;需要配置代理访问。可用nginx搭建代理服务。 TCP代理 通过nginx的stream模块可以直接代理TCP服务&#xff0c;步骤如下&#xff1a; 在/etc/nginx/下新建proxy文件夹&#xff0c;用于存放代理配置。此处…...

【瑞吉外卖 | day01】项目介绍+后台登录退出功能

文章目录 瑞吉外卖 — day011. 所需知识2. 软件开发整体介绍2.1 软件开发流程2.2 角色分工2.3 软件环境 3. 瑞吉外卖项目介绍3.1 项目介绍3.2 产品原型展示3.3 技术选型3.4 功能架构3.5 角色 4. 开发环境搭建4.1 数据库环境搭建4.2 Maven项目构建 5. 后台系统登录功能5.1 创建需…...

关于批量采集1688商品主图及链接的方式:软件采集/1688官方API接口数据采集

关于批量采集&#xff0c;我们通常用到的是软件 采集&#xff0c;或者通过1688官方API数据采集的形式&#xff1a;用户输入一组1688商品ID&#xff0c;一行一个&#xff0c;流程会自动逐个打开对应的1688商品详情页&#xff0c;采集主图的所有链接。 结果保存为表格的一行&…...

Shell 获取Hive表的location 信息

用shell 获取建表语句&#xff1a; hive -e "show create table ods_job.ods_job_tb"得到结果&#xff1a; CREATE TABLE ods_job.ods_job_tb(id bigint COMMENT id, auto int COMMENT job开启/关闭&#xff1a;0-关闭&#xff1b;1-开启, ....timeout_kill string…...

从零搭建教育管理系统:Java + Vue.js 教学-02

第三步:创建实体类和 Mapper 接口 现在我们已经设计好了数据库表,接下来使用 MyBatis-Plus 将这些表映射到 Java 对象,以便在代码中轻松地进行操作。 1. 创建实体类 在 src/main/java/<your_package>/entity 目录下 (如果没有该目录,请手动创建),创建与数据库表对应…...

VSCode + GDB + J-Link 单片机程序调试实践

VSCode GDB J-Link 单片机程序调试实践 本文介绍如何创建VSCode的调试配置&#xff0c;如何控制调试过程&#xff0c;如何查看修改各种变量。 安装调试插件 在 VSCode 扩展窗口搜索安装 Cortex-Debug插件 创建调试配置 在 Run and Debug 窗口点击 create a launch.json …...

grpc学习golang版( 五、多proto文件示例 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件2.1 公共proto文件2.2 语音唤醒proto文…...

LeetCode 106 从中序与后序遍历序列构造二叉树

根据中序遍历和后序遍历的性质&#xff0c;还原二叉树&#xff0c;详细见注释 TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {//空&#xff0c;直接返回nullif(inorder.size() 0) return nullptr;//一个&#xff0c;返回一个nod…...

Vue Router的深度解析

引言 在现代Web应用开发中&#xff0c;客户端路由已成为实现流畅用户体验的关键技术。与传统的服务器端路由不同&#xff0c;客户端路由通过JavaScript在浏览器中控制页面内容的更新&#xff0c;避免了页面的全量刷新。Vue Router作为Vue.js官方的路由解决方案&#xff0c;以其…...

YOLO-V2

一、V2版本细节升级 1、YOLO-V2&#xff1a; 更快&#xff01;更强 1.1 做的改进内容 1. YOLO-V2-Batch Normalization V2版本舍弃Dropout&#xff0c;卷积后每一层全部加入Batch Normalization网络的每一层的输入都做了归一化&#xff0c;收敛相对更容易经过Batch Norma…...

pmp考试的通过标准是什么?

PMP考试的是否通过并不是依据类似其他考试的数值成绩&#xff0c;是通过考生收到邮件通知后去主动查询具体的页面得知的。查询页除了电子证书的下载方式&#xff0c;还有成绩报告单的选项以及成绩饼状图&#xff0c;具体如下&#xff1a; 页面中显示“PASS”表示考试通过。 显…...

不懂PyQt5垂直布局?只需3分钟即可学会

PyQt5中实现垂直布局&#xff0c;主要使用QVBoxLayout类。该布局管理器将子控件垂直排列&#xff0c;并可以根据需要自动调整大小。使用QVBoxLayout可以方便地构建从上到下排列的界面元素。 import sys from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPus…...

从零开始实现大语言模型(二):文本数据处理

1. 前言 神经网络不能直接处理自然语言文本&#xff0c;文本数据处理的核心是做tokenization&#xff0c;将自然语言文本分割成一系列tokens。 本文介绍tokenization的基本原理&#xff0c;OpenAI的GPT系列大语言模型使用的tokenization方法——字节对编码(BPE, byte pair en…...

生物分子生物学实验过程的自动化与智能监控系统设计

开题报告&#xff1a;生物分子生物学实验过程的自动化与智能监控系统设计 一、引言 随着生物科学技术的飞速发展&#xff0c;生物分子生物学实验在科研、医疗、农业等领域的应用日益广泛。然而&#xff0c;传统的生物分子生物学实验过程大多依赖于人工操作&#xff0c;存在操…...

linux的shell脚本编程详解

Shell 脚本是一种用于自动化任务的脚本语言&#xff0c;在 Linux 和其他类 Unix 操作系统中非常流行。它通常用于任务自动化、系统管理和批处理。编写 Shell 脚本并使其自动化编译过程&#xff08;例如使用 gcc 编译 C/C 程序&#xff09;是一种常见的任务。 以下是一个详细的…...

Redis 7.x 系列【11】数据类型之位图(Bitmap)

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 基本命令2.1 SETBIT2.2 GETBIT2.3 BITCOUNT2.4 BITPOS2.5 BITFIELD2.6 BITF…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...