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

Kotlin中的destructuring解构声明

开发中有时只是想分解一个包含多个字段的对象来初始化几个单独的变量。要实现这一点,可以使用Kotlin的解构声明。

本文主要了解:

1、如何使用解构声明这种特性
       2、底层是如何实现的
       3、如何在你自己的类中实现它

1、解构声明的使用

解构声明(Destructuring Declarations)概念:将对象所包含的字段视为一组独立的变量

解构声明允许我们这样定义局部变量:

//Perosn对象定义
data class Person(var id: Int, var name: String, var age: Int)fun main() {val person = Person(1, "张三", 20)//解构声明,id/name/age新定义的三个变量分别对应Person中的三个字段val(id, name, age) = person//访问解构声明的name字段println("这个人的名字: $name")
}

在处理返回值时,也可以使用解构声明:

fun getPersonInfo() = Person(2, "李四", 35)
val(id, name, age) = getPersonInfo()

或者如果我们需要从一个函数中返回两个值:

fun getTwoValues(): Pair<Int, String> {// ...return Pair(1, "success")
}val (result, status) = getTowValues()

使用for循环迭代集合可以通过解构声明完成,如下所示:

for ((a, b) in collection) { ... }

上面代码中变量a和b对应返回集合中的前两个元素。

然而,在Map中,如下面代码中,变量a和b将分别对应的是key和value:

var map: HashMap<Int, Person> = HashMap()map.put(1, person)for((key, value) in map){println("Key: $key, Value: $value")
}

默认情况下,所有数据类data calss都支持解构。

你可以决定只使用类字段中的一个变量子集:

//Perosn对象定义
data class Person(var id: Int, var name: String, var age: Int)fun main() {val person = Person(1, "张三", 20)//val(id, name, age) = person//结构Person类中前两个字段val(id, name) = person
}

解构不允许你准确地选择你想要使用的字段;它总是使用前n个字段,其中n是您声明的变量的数量。这样做的缺点是很容易犯错误。例如,下面的代码片段可能会提供一个意想不到的结果:

37ad8ddf5b8b602a1222bdee9e859818.png


如果你只需要一个非连续字段的子集,对那些你不感兴趣的字段使用_,Kotlin会跳过它们。上面的例子变成:

fun main() {val person = Person(1, "张三", 20)val (_,name,age) = personprintln(name)println(age)
}

2、底层实现:

让我们看看一个反编译的数据类,看看发生了什么。我们将只关注为解构而生成的函数。

要查看Java反编译代码,请转到Tools -> Kotlin -> Show Kotlin Bytecode,然后按下Decompile按钮。

public final class Person {private int id;@NotNullprivate String name;private int age;//...public Person(int id, @NotNull String name, int age) {//...}public final int component1() {return this.id;}@NotNullpublic final String component2() {return this.name;}public final int component3() {return this.age;}}

我们看到,在主构造函数中声明的每个属性都会生成名为componentN的函数,其中N是主构造函数中字段的索引

3、实现解构

正如我们所看到的,解构依赖于componentN函数。因此,如果您想将解构功能添加到不支持它的类中,那么只需实现相应的componentN操作符函数即可。确保在它们前面加上operator关键字。

class Student(val name: String,val age: String
) {operator fun component1(): String = nameoperator fun component2(): Int = age...
}

Kotlin允许您通过扩展函数为不属于自己的类实现解构。例如,Map.Entry只是一个接口,默认情况下它不支持解构。为了克服这个问题,创建了component1()和component2()函数,它们返回Map.Entry的键和值。

具体可以看Map.Entry源码或者API文档:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/-entry/

总结

当您需要将对象的字段分解为变量时,请使用解构。在底层,解构是通过提供componentN操作符函数实现的,因此您可以自己为您认为从该功能中受益的类提供这些操作符函数。

相关文章:

Kotlin中的destructuring解构声明

开发中有时只是想分解一个包含多个字段的对象来初始化几个单独的变量。要实现这一点&#xff0c;可以使用Kotlin的解构声明。本文主要了解&#xff1a;“1、如何使用解构声明这种特性 2、底层是如何实现的 3、如何在你自己的类中实现它1、解构声明的使用解构声明&a…...

Kubernetes Pod 水平自动伸缩(HPA)

Pod 自动扩缩容 之前提到过通过手工执行kubectl scale命令和在Dashboard上操作可以实现Pod的扩缩容&#xff0c;但是这样毕竟需要每次去手工操作一次&#xff0c;而且指不定什么时候业务请求量就很大了&#xff0c;所以如果不能做到自动化的去扩缩容的话&#xff0c;这也是一个…...

钉钉、企业微信和飞书向“钱”看

在急剧变革的时候&#xff0c;不管黑猫白猫&#xff0c;要抓到老鼠才算好猫。如今&#xff0c;各互联网企业早已进入降本增效的新阶段。勒紧裤腰带过日子之下&#xff0c;能不能盈利、商业化空间有多大&#xff0c;就成为各个业务极为重要的考核指标。在各业务板块中&#xff0…...

网上购物网站的设计

技术&#xff1a;Java、JSP等摘要&#xff1a;本文介绍了JSP和JAVA等相关技术&#xff0c;针对网上购物系统的实际需求&#xff0c;设计开发了一个基于JSP的小型电子商务网站也就是网上购物系统&#xff0c;。在设计开发中&#xff0c;采用的是SSH框架&#xff08;strutsspring…...

【Java学习笔记】8.Java 运算符

Java 运算符 计算机的最基本用途之一就是执行数学运算&#xff0c;作为一门计算机语言&#xff0c;Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组&#xff1a; 算术运算符关系运算符位运算符逻辑运算符赋值运算符其他运算符 算术运算符 算术运算符…...

RHCSA-使用命令管理文件(3.6)

硬链接与软链接基本操作&#xff1a; 创建软硬连接的命令&#xff1a;ln 硬链接&#xff1a;ln 源文件&#xff08;已经存在的文件&#xff09; 链接文件名&#xff08;新建&#xff09; 软连接&#xff1a;ln -s 源文件&#xff08;已存在的文件&#xff09; 快捷方式文件名…...

socket聊天室--socket的建立

socket聊天室–socket实现 文章目录 socket聊天室--socket实现socket()bind()listen()accept()connect()发送接收read()函数recv()函数write()函数send()函数close()关闭套接字IP 地址格式转换函数socket() #include <sys/types...

Raft图文详解

Raft图文详解 refer to: Raft lecture (Raft user study) - YouTube Raft PDF Raft算法详解 - 知乎 (zhihu.com) 今天来详细介绍一下Raft协议 Raft是来解决公式问题的协议&#xff0c;那么什么是共识呢&#xff1f; 在分布式系统里面&#xff0c;consensus指的是多个节点对…...

春季出游,学会这些功能,让你旅途更舒心

春意盎然&#xff0c;万物复苏&#xff0c;春天正是旅游观光的好时节&#xff0c;相信不少小伙伴已经做好了出游的准备。想拥有好的心情&#xff0c;除了美食美景&#xff0c;好的出游神器也必不可少&#xff0c;好的出游神器能让我们的旅途更舒心&#xff0c;一起来看看是哪些…...

【华为OD机试真题java、python、c++、jsNode】简单的自动曝光【2022 Q4 100分】(100%通过)

代码请进行一定修改后使用,本代码保证100%通过率。本文章提供java、python、c++、jsNode四种代码 题目描述 一个图像有n个像素点,存储在一个长度为n的数组img里,每个像素点的取值范围[0,255]的正整数。 请你给图像每个像素点值加上一个整数k(可以是负数),得到新图newImg…...

react学习笔记-1:创建项目

安装nodejs https://nodejs.org/dist/v18.14.2/node-v18.14.2-x64.msi 修改国内源&#xff1a;npm config set registry https://registry.npm.taobao.org 使用create-react-app脚手架创建项目 安装脚手架 npm install -g create-react-app 全局安装&#xff0c;可以在任意的…...

vulnhub five86-2

总结&#xff1a;sudo -l&#xff0c;抓流量包&#xff0c;搜索引擎。。 目录 下载地址 漏洞分析 信息收集 网站渗透 ​编辑 反弹shell提权 下载地址 Five86-2.zip (Size: 1.7 GB)Download (Mirror): https://download.vulnhub.com/five86/Five86-2.zip使用&#xff1a;下…...

OpenCV入门(四)快速学会OpenCV3画基本图形

OpenCV入门&#xff08;四&#xff09;快速学会OpenCV3画基本图形 1.画点 在OpenCV中&#xff0c;点分为2D平面中的点和3D平面中的点&#xff0c;区别就是3D中点多了一个z坐标。我们首先介绍2D中的点&#xff0c;坐标为整数的点可以直接用(x, y)代替&#xff0c;其中x是横坐标…...

【MAC OS 命令行】Redis的安装、启动和停止。就是如此简单

目录Mac 安装 Redis使用 Homebrew 安装 Redis总结Mac 安装 Redis 使用 Homebrew 安装 Redis 如果没有安装 Homebrew&#xff0c;先安装 Homebrew 执行命令&#xff1a; 方法一、brew 官网的安装脚本 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homeb…...

Leetecode 661. 图片平滑器

图像平滑器 是大小为 3 x 3 的过滤器&#xff0c;用于对图像的每个单元格平滑处理&#xff0c;平滑处理后单元格的值为该单元格的平均灰度。 每个单元格的 平均灰度 定义为&#xff1a;该单元格自身及其周围的 8 个单元格的平均值&#xff0c;结果需向下取整。&#xff08;即&…...

剑指 Offer II 020. 回文子字符串的个数

题目链接 剑指 Offer II 020. 回文子字符串的个数 mid 题目描述 给定一个字符串 s&#xff0c;请计算这个字符串中有多少个回文子字符串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。 示例 1&#xff1a; 输入…...

Python实现多键字典

实现背景 在许多场景中&#xff0c;有时需要通过多种信息来获取某个特定的值&#xff0c;而各种编程语言&#xff08;包括Python&#xff09;使用的字典&#xff08;Dict&#xff09;数据结构通常只支持单个键值寻值key-val对&#xff0c;即“一对一”&#xff08;一个键对应一…...

【python socket】实现websocket服务端

一、获取握手信息首先通过如下代码&#xff0c;我们使用socket来获取客户端的握手信息import socketsock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(("127.0.0.1", 8002)) sock.li…...

PANGO的CFG那些事

先来看位于VCCIOCFG这个bank上引脚&#xff0c; MODE JTAG时&#xff0c;MODExxx. except 3’b000. 禁止设置为3’b000. Slave Parallel时&#xff0c;MODE 3’b110&#xff0c;不常用。 Slave Serial时&#xff0c;MODE 3’b111&#xff0c;不常用。 Master SPI 时&…...

路由协议(OSPF、ISIS、BGP)实验配置

目录 OSPF基础实验 建立OSPF邻居 配置虚连接 配置接口的网络类型 配置特殊区域 配置路由选路 配置路由过滤 ISIS基础实验配置 配置ISIS邻居建立 配置认证 配置路由扩散 配置路由过滤 配置定时器 BGP基础实验配置 建立BGP对等体 建立IBGP对等体 建立EBGP对等体…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#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…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...