当前位置: 首页 > 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…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...