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

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...