四、Kotlin 表达式
1. 常量 & 变量
1.1 可读写变量(var)
 
var x = initValue // x 称为可读写变量
注意:当 var 声明的变量做成员属性时,默认提供 setter/getter 方法。
1.2 只读变量(val)
 
val x = initValue // x 称为只读变量
注意:
- 当 val声明的变量做成员属性时,默认只提供getter方法。
- 当 val声明的变量做全局变量或局部变量时,相当于Java中被final修饰的常量。
1.3 常量(const val)
 
const val x = initValue // x  称为常量
注意:
- const修饰的常量只能定义在全局范围内。
- const只能修饰基本类型的变量。
- const修饰的变量的初始值只能是字面量。
1.4 常量引用
常量引用即:使用 val 声明的类类型的变量。
val p = Person("xiaoming") 
其中:
- Person对象创建在堆区,变量- p被- val修饰,是一个常用引用。
- 由于 p是常用引用,所以不能修改p的指向,但可以修改p对象中的成员。
2. if-else 表达式
 
Java 中 if-else 只是一个语句,对应一个三目运算符 “?:” 构成的条件表达式 express ? statement1 : statement2
Kotlin 中 if-else 即是一个语句,又可以作为一个表达式使用。
所以
Kotlin中没有三目运算符 “?:” 构成的条件表达式express? statement1: statement2
// if-else 语句
if(express) {statement1
} else {statement2
}// if-else 表达式
val x = if (express) statement1 else statement2 // if-else 表达式可以返回结果值
3. when 表达式
 
Kotlin 中的 when 表达式跟 while 循环语句没有任何关系。
3.1 Kotlin 中的 when 表达式相当于 Java 中的 switch 语句
 
Java 中:
swtich(a)  {case 0:c = 5break;case 1:c = 100break;default:c = 20;
}
Kotlin 中:
when(a) {0 -> c = 51 -> c = 100else -> c = 20
}
其中:
1. value -> 相当于 Java 中的 case value:
2. else -> 相当于 Java 中的 default:
3. 省略了 break 语句
由于 when(condition){...} 是一个表达式,而表达式总会有结果值,所以还可以写成:
// "->" 后面的就是when表达式的结果值
c = when(a) {0 -> 51 -> 100else -> 20
}
3.2 when 表达式的条件可以放到代码块的分支中
 
when {// 条件表达式 x is String 保证了 x 是不可空类型 String,所以 Kotlin 会把变量 x 智能转换为不可空类型 Stringx is String -> c = x.length x == 1 -> c = 100else -> c = 20
}
同样地,由于 when 是一个表达式,会返回结果值,所以还可以写成:
c = when {x is String -> x.lengthx == 1 -> 100else -> 20
}
3.3 when 表达式的条件可以是一条赋值语句
 
c = when(val input = readLine()) { //变量 input 作为条件变量null -> 0  // input 为空时,when 表达式返回0else -> input.length // input 不为空时,when 表达式返回 input.length
}
4. try-catch 表达式
 
Kotlin 中的 try-catch 既可以作为语句,也可以作为表达式:
-  作为 try-catch语句时,用法基本同Java一样:try {c = a/b } catch (e: Exception) { // Kotlin中的参数声明一般是 "参数名: 参数类型", Java中则是 "参数类型 参数名"e.printStackTrace()c = 0 }
-  作为 try-catch表达式时,最后一条执行语句的结果作为返回结果值:c = try {a/b } catch (e: Exception) {e.printStackTrace()0 }
5. 运算符重载
Kotlin 官方文档:https://kotlinlang.org/docs/operator-overloading.html
可重载的运算符仅限
Kotlin官方文档中指定的运算符。
5.1 运算符重载函数定义
-  运算符重载函数定义时需要加关键字 operator
-  运算符重载函数可以是:全局函数、或成员方法、或扩展方法 
-  子类重写父类的运算符重载函数时,可以省略关键字 operator
5.2 运算符和运算符重载函数的对应关系
-  ==对应equals"str1" == "str2" <==> "str1".equals("str2")
-  +对应plusa + b <==> a.plus(b)
-  in对应containselement in list <==> list.contains(element)
-  []对应getval value = map[key] <==> val value = map.get(key)
-  []对应setmap[key] = value <==> map.set(key, value)
-  >对应compareToa > b <==> a.compareTo(b) > 0 // <, >=, <= 与之类似
-  ()对应invoke// func 为匿名函数 val func = fun(p1: T1, p2: T2, ...): ReturnType {...} func(p1, p2, ...) <==> func.invoke(p1, p2, ...)
5.3 示例

6. 函数体只有一条表达式时的简写形式
当函数的函数体中仅有一条表达式语句时,可以简写成:
fun funName(p1: T1, p2: T2, ...): ReturnType = expresssion
7. 中缀表达式
中缀表达式对应一个被关键字 infix 修饰的函数。
关键字
infix修饰的函数只能是成员方法或扩展方法。
示例 1:
/* 函数定义 */ // 函数体只有一个表达式 "Pair(this, that)", 所以可以写成简化形式
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)  /* 函数调用 */ // 其中,简化形式 2 to 3 称为中缀表达式
2 to 3  <==>  2.to(3)  
示例 2:
/* 函数定义 */ 
infix fun String.minus(len: Int): String = this.substring(len until length)/* 函数调用 */ // 其中简化形式 "HelloKoltin" minus 5 称为中缀表达式
val str = "HelloKotlin" minus 5  <==>  val str = "HelloKotlin".minus(5)  
8. 匿名函数
对于普通函数:
// 其中 funName 称为函数名
fun funName(p1: T1, p2: T2, ...): ReturnType {...}  
对应的匿名函数为:
// 其中 funRef 是函数类型为 (T1, T2, ...) -> ReturnType 的变量,接收一个匿名函数的函数引用
val funRef = fun()(p1: T1, p2: T2, ...): ReturnType {...}  
9. Lambda 表达式
 
9.1 Java 中的 Lambda 表达式
 
9.1.1 什么是函数式接口
只有一个抽象方法的接口称为函数式接口,如 Runnable 接口(只有一个抽象方法 run)。
9.1.2 Java 中的 Lambda 表达式与函数式接口的关系
 
- Java中的- Lambda表达式就是用来代替用于创建函数式接口对象的匿名内部类
- Java中的- Lambda表达式其实就是函数式接口的抽象方法的匿名函数实现
- Java中的- Lambda表达式的结果值就是一个函数式接口的实例对象
总的来说:Java 中的 Lambda 表达式其实就是一个匿名函数,这个匿名函数就是函数式接口的抽象方法。也就是说,Java 中的 Lambda 表达式就是在重写函数式接口的抽象方法。但是整个 Lambda 表达式的结果值,并不是函数式接口的抽象方法返回值,而是一个函数式接口的实例对象。
9.1.3 Java 中的 Lambda 表达式的使用场景
 
-  将 Lambda表达式赋给函数式接口类型的变量;
-  将 Lambda表达式作为函数式接口类型参数的实参;
-  将 Lambda表达式强制转换为函数式接口类型。
9.1.4 Java 中的 Lambda 表达式的语法
 
(T1 p1, T2 p2, ...) -> {...}  // 不需要显示指定返回值类型
特别地:
-  考虑到 Lambda表达式的使用场景,总能确定Lambda表达式对应的函数式接口,所以可以省略Lambda表达式的形参列表中的参数类型,即:(T1 p1, T2 p2, ...) -> {...} <==> (p1, p2, ...) -> {...}
-  当形参列表只有一个参数时,可以省略括号 “ ()”,即:p1 -> {...}
-  当形参列表没有参数时,不可以省略括号 “ ()”,即:() -> {...}
-  当 Lambda表达式中的函数体只有一条语句时,可以省略花括号 “{}”,即:(T1 p1, T2 p2, ...) -> statement
9.2 Kotlin 中的 Lambda 表达式
 
9.2.1 语法
{p1: T1, p2: T2, ... -> statement1statement2...statementN
}
注意:
-  以上 Lambda表达式对应一个函数类型为(T1, T2, ...) -> ReturnType的匿名函数。其中ReturnType由最后一条执行语句statementN的结果值确定。若statementN没有结果值,则ReturnType为Unit。
-  Kotlin的Lambda表达式的结果值是一个函数引用,所以可以将Lambda表达式赋给函数类型为(T1, T2, ...) -> ReturnType的变量。
-  当显示指定了变量的函数类型时, Lambda表达式的形参列表中的参数类型可以省略,如:val funRef: (T1, T2, ...) -> ReturnType = {p1, p2, ... ->statement1statement2...statementN // 最后一条语句的结果值必须是ReturnType }
-  当形参列表为空时,可以省略 “ p1: T1, p2: T2, ... ->”,如:val funRef: () -> ReturnType = {statement1statement2...statementN }
-  当形参列表只有一个参数时,可以使用默认参数 it:val funRef: (T1) -> ReturnType = {// 虽然没有声明形参列表,但存在一个 T1 类型的默认参数 it }
-  当存在一个函数,且函数形参列表的最后一个形参是函数类型,若调用该函数时,使用 Lambda表达式作为最后一个函数类型形参的实参,则Lambda表达式可以写在函数调用运算符 “()” 的后面。特别地,当函数的形参列表只是一个函数类型的参数时,还可以省略函数调用运算符 “ ()”
9.2.2 Kotlin 中的 Lambda 表达式 & Java 中的 Lambda 表达式的区别
 
Java 中的 Lambda 表达式的结果值是一个函数式接口的实例对象。
Kotlin 中的 Lambda 表达式的结果值是一个匿名函数的函数引用。
Java 的 Lambda 表达式:
Runnable runable = () -> {// Java 的 Lambda表达式就是在重写 Runnable 接口的 run 方法...
}
Kotlin 的 Lambda 表达式:
val funRef = {// Kotlin 的 Lambda 表达式就是一个匿名函数...
}
相关文章:
 
四、Kotlin 表达式
1. 常量 & 变量 1.1 可读写变量(var) var x initValue // x 称为可读写变量注意:当 var 声明的变量做成员属性时,默认提供 setter/getter 方法。 1.2 只读变量(val) val x initValue // x 称为只…...
 
Web开发4:单元测试
在Web开发中,单元测试是一种重要的开发实践,它可以帮助我们确保代码的质量和可靠性。通过编写和运行单元测试,我们可以验证代码的正确性,减少错误和缺陷,并提高代码的可维护性。本文将介绍单元测试的概念、好处以及如何…...
Ubuntu 16 让ufw防火墙控制docker容器中所有端口
使用docker ps 查询docker在运行端口。 rootai-0003:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS …...
 
<蓝桥杯软件赛>零基础备赛20周--第18周--动态规划初步
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周。 在QQ群上交流答疑&am…...
vb如何获取鼠标形状的特征码
vb如何获取鼠标形状的特征码 好像按键精灵有一个GetCursorShape()函数可以获取特征码,不知道VB6能不能实现类似的功能? 附注: 1 最好是机器无关的,不是也可以。 2 特征码就是一串数字,用来区分不同的鼠标形状。 3 获取…...
 
chroot: failed to run command ‘/bin/bash’: No such file or directory
1. 问题描述及原因分析 在busybox的环境下,执行 cd rootfs chroot .报错如下: chroot: failed to run command ‘/bin/bash’: No such file or directory根据报错应该rootfs文件系统中缺少/bin/bash,进入查看确实默认是sh,换成…...
 
蓝桥杯备战——2.矩阵键盘
1.分析原理图 由上图可以看到若J5跳线帽接地,就S4~S7就可以当做四路独立按键,若接到P44,则就是4*4的矩阵键盘。 2.独立按键处理 相对传统的按键延时消抖方案,这里我采用更高效,更经典,更偏向产品级应用的…...
 
Docker部署思维导图工具SimpleMindMap并实现公网远程访问
文章目录 1. Docker一键部署思维导图2. 本地访问测试3. Linux安装Cpolar4. 配置公网地址5. 远程访问思维导图6. 固定Cpolar公网地址7. 固定地址访问 SimpleMindMap 是一个可私有部署的web思维导图工具。它提供了丰富的功能和特性,包含插件化架构、多种结构类型&…...
 
机器学习实验2——线性回归求解加州房价问题
文章目录 🧡🧡实验内容🧡🧡🧡🧡数据预处理🧡🧡代码缺失值处理特征探索相关性分析文本数据标签编码数值型数据标准化划分数据集 🧡🧡线性回归🧡&am…...
 
宝塔+nextcloud+docker+Onlyoffice 全开启https
折腾了我三天的经验分享 1.宝塔创建网站 nextcloud版本为28.0.1 php8.2 ,导入nextcloud绑定域名对应的证书 ,不用创建mysql 因为nextcloud 要求是mariadb:10.7 宝塔里没有,就用docker安装一个 端口设置为3307 将数据库文件映射出来/ww…...
呼吸机电机控制主控MCU方案
呼吸机是一种能代替、控制或改变人的正常生理呼吸,增加肺通气量,改善呼吸功能,减轻呼吸功消耗,节约心脏储备能力的装置。呼吸机连接一条管子到患者的嘴或鼻子,氧气量可以通过监视器加以控制。 基于灵动微控制器的呼吸…...
 
gitlab备份-迁移-升级方案9.2.7升级到15版本最佳实践
背景 了解官方提供的版本的升级方案 - GitLab 8: 8.11.Z 8.12.0 8.17.7 - GitLab 9: 9.0.13 9.5.10 9.2.7 - GitLab 10: 10.0.7 10.8.7 - GitLab 11: 11.0.6 11.11.8 - GitLab 12: 12.0.12 12.1.17 12.10.14 - GitLab 13: 13.0.14 13.1.11 13.8.8 13.12.15 - G…...
redis面试题合集-基础
前言 又来到每日的复习时刻,昨天我们学习了mysql相关基础知识,还有分布式数据库介绍(后续总结时再持续更新)。今日继续学习缓存杀器:redis redis基础面试题合集 什么是Redis? Redis是一个开源的、内存中…...
(Unity)C# 中的字符串格式化
前言 在软件开发中,理解和掌握字符串的格式化及调试技巧对于编写高效和可维护的代码至关重要。 字符串插值 ($ 符号) 在 C# 中,字符串插值是通过在字符串前加 $ 符号来实现的。这允许我们将变量、表达式或函数调用直接嵌入到字符串中。 string name &qu…...
 
【项目日记(五)】第二层: 中心缓存的具体实现(上)
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:项目日记-高并发内存池⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你做项目 🔝🔝 开发环境: Visual Studio 2022 项目日…...
 
使用PSIM软件生成DSP28335流水灯程序
最近在学习DSP28335芯片,然后在使用PSIM仿真软件时发现这个仿真软件也支持28335芯片,于是就想学习下如何在PSIM软件中使用DSP28335芯片。在PSIM自带的官方示例中有使用DSP28335芯片的相关例子。 工程下载链接 https://download.csdn.net/download/qq_20…...
 
【iOS ARKit】人脸检测追踪基础
在计算机人工智能(Artificial Inteligence,AI)物体检测识别领域,最先研究的是人脸检测识别,目前技术发展最成熟的也是人脸检测识别。人脸检测识别已经广泛应用于安防、机场、车站、闸机、人流控制、安全支付等众多社会领域&#x…...
 
ES的一些名称和概念总结
概念 先看看ElasticSearch的整体架构: 一个 ES Index 在集群模式下,有多个 Node (节点)组成。每个节点就是 ES 的Instance (实例)。每个节点上会有多个 shard (分片), P1 P2 是主分片, R1 R2…...
 
Javaweb之SpringBootWeb案例之阿里云OSS服务集成的详细解析
2.3.3 集成 阿里云oss对象存储服务的准备工作以及入门程序我们都已经完成了,接下来我们就需要在案例当中集成oss对象存储服务,来存储和管理案例中上传的图片。 在新增员工的时候,上传员工的图像,而之所以需要上传员工的图像&…...
 
【GitHub项目推荐--不错的 Go 学习项目】【转载】
开源实时性能分析平台 Pyroscope 是基于 Go 的开源实时性能分析平台,在源码中添加几行代码 pyroscope 就能帮你找出源代码中的性能问题和瓶颈、CPU 利用率过高的原因,调用树展示帮助你理解程序,支持 Go、Python、Ruby 语言。 Pyroscope 可以…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
 
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
 
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
 
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
 
Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...
 
代理服务器-LVS的3种模式与调度算法
作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器,其中以Nginx为主,本章我们来讲解几个代理软件:…...
 
信息收集:从图像元数据(隐藏信息收集)到用户身份的揭秘 --- 7000
目录 🌐 访问Web服务 💻 分析源代码 ⬇️ 下载图片并保留元数据 🔍 提取元数据(重点) 👤 生成用户名列表 🛠️ 技术原理 图片元数据(EXIF 数据) Username-Anarch…...
