Kotlin 2.1.0 入门教程(十)if、when
if 表达式
if 是一个表达式,它会返回一个值。
不存在三元运算符(condition ? then : else),因为 if 在这种场景下完全可以胜任。
var max = aif (a < b) max = bif (a > b) {max = a
} else {max = b
}max = if (a > b) a else bval maxLimit = 1val maxOrLimit = if (maxLimit > a) maxLimit else if (a > b) a else b
if 表达式的分支可以是代码块。在这种情况下,代码块中的最后一个表达式就是该代码块的值。
val max = if (a > b) {print("Choose a")a
} else {print("Choose b")b
}
如果使用 if 作为表达式,例如用于返回它的值或将它赋值给一个变量,那么 else 分支是必需的。
when 表达式和语句
when 是一种基于多个可能的值或条件运行代码的条件表达式。它类似于 Java、C 等语言中的 switch 语句。
val x = 2when (x) {1 -> print("x == 1")2 -> print("x == 2")else -> print("x is neither 1 nor 2")
}
when 会依次将它的参数与所有分支的条件进行匹配,直到某个分支的条件被满足为止。
你可以以几种不同的方式使用 when。首先,你可以将 when 用作表达式或语句。作为表达式,when 会返回一个值,供你在代码中后续使用。作为语句,when 用于完成某个操作,而不会返回任何进一步使用的值。
// 表达式。
// 返回一个字符串,该字符串被赋值给变量 text。
val text = when (x) {1 -> "x == 1"2 -> "x == 2"else -> "x is neither 1 nor 2"
}
// 语句。
// 不返回任何值,但会触发一个打印语句。
when (x) {1 -> print("x == 1")2 -> print("x == 2")else -> print("x is neither 1 nor 2")
}
可以使用带有或不带有对象的 when。无论是否在 when 中使用对象,表达式或语句的行为都是相同的。我们建议在可能的情况下使用带有对象的 when,因为它清晰地展示你在检查什么,使你的代码更易于阅读和维护。
// 带对象。
when (x) { ... }
// 不带对象。
when { ... }
根据你如何使用 when,对于是否需要在分支中覆盖所有可能的情况有不同的要求。
如果你将 when 用作语句,你不需要覆盖所有可能的情况。在下面的例子中,并没有覆盖所有情况,因此当不匹配任何分支时,不会发生任何事情。但也不会出现错误:
val x = 3
when (x) {// 并未覆盖所有情况。1 -> print("x == 1")2 -> print("x == 2")
}
在 when 语句中,各个分支的值会被忽略。就像 if 一样,每个分支可以是一个代码块,而代码块的值是块中最后一个表达式的值。
如果你将 when 用作表达式,那么你必须覆盖所有可能的情况,也就是说,它必须是穷尽的。第一个匹配分支的值将成为整个表达式的值。如果你没有覆盖所有情况,编译器会报错。
如果你的 when 表达式有一个对象,你可以使用 else 分支来确保覆盖所有可能的情况,但这并不是强制性的。例如,如果对象是一个布尔类型、枚举类、密封类,或者它们的可空类型,那么你可以不使用 else 分支来覆盖所有情况。例如:
enum class Bit {ZERO, ONE
}val numericValue = when (getRandomBit()) {// 不需要 else 分支,因为所有可能的情况都已经被覆盖了。Bit.ZERO -> 0Bit.ONE -> 1
}
如果你的 when 表达式没有对象,那么你必须有一个 else 分支,否则编译器会报错。当没有其他分支条件被满足时,else 分支会被执行。例如:
val number = 5val result = when {number > 0 -> "Positive"number < 0 -> "Negative"// 必须有 else 分支,因为没有对象。else -> "Zero"
}
when 表达式和语句提供了多种方法来简化代码、处理多个条件以及执行类型检查。
你可以通过在单行中用逗号分隔多个条件,为多个案例定义共同的行为。例如:
val x = 2when (x) {1, 2, 3 -> println("x is 1, 2, or 3")4, 5, 6 -> println("x is 4, 5, or 6")else -> println("x is not in the range 1 to 6")
}
你可以使用任意表达式(不仅仅是常量)作为分支条件。例如:
val x = 5
val y = 10when (x) {y -> println("x is equal to y")y + 5 -> println("x is equal to y + 5")y - 5 -> println("x is equal to y - 5")else -> println("x is not equal to y, y + 5, or y - 5")
}
在这个例子中,y、y + 5 和 y - 5 都是作为分支条件的表达式。when 会根据 x 的值与这些表达式的结果进行比较,从而选择对应的分支。这种方式使得 when 的条件更加灵活,可以用于更复杂的逻辑判断。
你还可以通过 in 或 !in 关键字来检查一个值是否包含在某个范围或集合中:
when (x) {in 1 .. 10 -> print("x is in the range")in validNumbers -> print("x is valid")!in 10 .. 20 -> print("x is outside the range")else -> print("none of the above")
}
此外,你可以通过 is 或 !is 关键字来检查一个值是否是某种特定类型。由于智能类型转换,你可以直接访问该类型的成员函数和属性,而无需额外的检查。
fun hasPrefix(x: Any) = when(x) {is String -> x.startsWith("prefix")else -> false
}
你可以将 when 用作 if-else if 链的替代品。如果没有对象,分支条件就是布尔表达式。第一个条件为 true 的分支会被执行:
when {x.isOdd() -> print("x is odd")y.isEven() -> print("y is even")else -> print("x + y is odd")
}
你可以通过以下语法在变量中捕获对象:
fun Request.getBody() =when (val response = executeRequest()) {is Success -> response.bodyis HttpError -> throw HttpException(response.status)}
在 when 表达式或语句的主体中引入的变量的作用域仅限于该 when 表达式或语句的内部。
when 表达式中的守护条件
守护条件是一个实验性功能,可能会随时发生变化。
守护条件允许你在 when 表达式的分支中包含多个条件,从而使复杂的控制流程更加明确和简洁。你可以在带有对象的 when 表达式或语句中使用守护条件。
要在分支中包含守护条件,请将其放在主条件之后,并用 if 分隔。
sealed interface Animal {data class Cat(val mouseHunter: Boolean) : Animaldata class Dog(val breed: String) : Animal
}fun feedAnimal(animal: Animal) {when (animal) {is Animal.Dog -> feedDog()is Animal.Cat if !animal.mouseHunter -> feedCat()else -> println("Unknown animal")}
}
在一个 when 表达式中,你可以同时使用带有守护条件和没有守护条件的分支。带有守护条件的分支中的代码只有在主条件和守护条件都为 true 时才会执行。如果主条件不满足,守护条件不会被评估。
如果你在没有 else 分支的 when 语句中使用守护条件,并且没有任何条件匹配,那么没有任何分支会被执行。
否则,如果你在没有 else 分支的 when 表达式中使用守护条件,编译器会要求你声明所有可能的情况,以避免运行时错误。
此外,守护条件还支持 else if 的功能。
when (animal) {// 检查 animal 是否是 Dog。is Animal.Dog -> feedDog()// 检查 animal 是否是 Cat 并且不是 mouseHunter。is Animal.Cat if !animal.mouseHunter -> feedCat()// 如果前面的条件都不匹配,并且 animal.eatsPlants 为 true,则此。else if animal.eatsPlants -> giveLettuce()// 如果前面的条件都不匹配,则此。else -> println("Unknown animal")
}
你可以在一个分支中通过使用布尔运算符 && 或 || 组合多个守护条件。为了避免混淆,请使用括号将布尔表达式括起来。
when (animal) {is Animal.Cat if (!animal.mouseHunter && animal.hungry) -> feedCat()
}
你可以在任何带有对象的 when 表达式或语句中使用守护条件,但有一个例外,当你的条件是通过逗号分隔的多个值时,例如 0, 1 -> print("x == 0 or x == 1"),这种情况下不能使用守护条件。
要在命令行界面中启用守护条件,运行以下命令:
kotlinc -Xwhen-guards main.kt
要在 Gradle 中启用守护条件,将以下代码添加到 build.gradle.kts 文件中:
kotlin {compilerOptions {freeCompilerArgs.add("-Xwhen-guards")}
}
相关文章:
Kotlin 2.1.0 入门教程(十)if、when
if 表达式 if 是一个表达式,它会返回一个值。 不存在三元运算符(condition ? then : else),因为 if 在这种场景下完全可以胜任。 var max aif (a < b) max bif (a > b) {max a } else {max b }max if (a > b) a…...
AJAX项目——数据管理平台
黑马程序员视频地址: 黑马程序员——数据管理平台 前言 功能: 1.登录和权限判断 2.查看文章内容列表(筛选,分页) 3.编辑文章(数据回显) 4.删除文章 5.发布文章(图片上传࿰…...
华为云搭建微信小程序商城后台
目录 安装宝塔界面 配置运行环境 1. 修改默认用户名密码 2. 修改默认端口号 3. 安装依赖软件 4. 安装商城 配置商城 1. 点击下一步进行商城环境检测 2. 将安装ShopXO成功后的弹窗信息填写到配置界面 3. 点击安装 发布小程序 源代码地址 1. 下载HBuilderX 2. 导入插…...
5、大模型的记忆与缓存
文章目录 本节内容介绍记忆Mem0使用 mem0 实现长期记忆 缓存LangChain 中的缓存语义缓存 本节内容介绍 本节主要介绍大模型的缓存思路,通过使用常见的缓存技术,降低大模型的回复速度,下面介绍的是使用redis和mem0,当然redis的语义…...
Windows下AMD显卡在本地运行大语言模型(deepseek-r1)
Windows下AMD显卡在本地运行大语言模型 本人电脑配置第一步先在官网确认自己的 AMD 显卡是否支持 ROCm下载Ollama安装程序模型下载位置更改下载 ROCmLibs先确认自己显卡的gfx型号下载解压 替换替换rocblas.dll替换library文件夹下的所有 重启Ollama下载模型运行效果 本人电脑配…...
代码随想录day09
151.反转字符串中的单词,需二刷 //先去除多余空格,再反转所有字符,再反转单词,即可反转字符串中的单词 void removeWhiteSpace(string& s){int slowIndex 0;for(int fastIndex 0; fastIndex < s.size(); fastIndex){if(…...
Racecar Gym 总结
1.Racecar Gym 简介 Racecar Gym 是一个基于 PyBullet 物理引擎 的自动驾驶仿真平台,提供 Gymnasium(OpenAI Gym) 接口,主要用于强化学习(Reinforcement Learning, RL)、多智能体竞速(Multi-Ag…...
【C++高并发服务器WebServer】-15:poll、epoll详解及实现
本文目录 一、poll二、epoll2.1 相对poll和select的优点2.2 epoll的api2.3 epoll的demo实现2.5 epoll的工作模式 一、poll poll是对select的一个改进,我们先来看看select的缺点。 我们来看看poll的实现。 struct pollfd {int fd; /* 委托内核检测的文件描述符 */s…...
Visual Studio 2022 中使用 Google Test
要在 Visual Studio 2022 中使用 Google Test (gtest),可以按照以下步骤进行: 安装 Google Test:确保你已经安装了 Google Test。如果没有安装,可以通过 Visual Studio Installer 安装。在安装程序中,找到并选择 Googl…...
Office/WPS接入DeepSeek等多个AI工具,开启办公新模式!
在现代职场中,Office办公套件已成为工作和学习的必备工具,其功能强大但复杂,熟练掌握需要系统的学习。为了简化操作,使每个人都能轻松使用各种功能,市场上涌现出各类办公插件。这些插件不仅提升了用户体验,…...
Meta AI 最近推出了一款全新的机器学习框架ParetoQ,专门用于大型语言模型的4-bit 以下量化
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
操作系统—进程与线程
补充知识 PSW程序状态字寄存器PC程序计数器:存放下一条指令的地址IR指令寄存器:存放当前正在执行的指令通用寄存器:存放其他一些必要信息 进程 进程:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位…...
团队:前端开发工期参考 / 防止工期不足、过足、工期打架
一、前端开发工期参考 序号功能 / 模块 / 页面 / 描述pc端(数值为比例)小程序端(数值为比例)1简单页面 / 常规页面1:12复杂页面(功能复杂 / 逻辑复杂)1:1.5 / 1:2 / …...
APL语言的云计算
APL语言的云计算:一种灵活而高效的编程方式 引言 随着信息技术的迅猛发展,云计算已经成为现代计算的重要组成部分。云计算不仅带来了计算资源的高效利用,也引发了新一轮的技术革命。在这个背景下,APL(A Programming …...
idea启动报错# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffccf76e433
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc0x00007ffccf76e433, pid17288, tid6696 # # JRE version: (11.0.248) (build ) # Java VM: OpenJDK 64-Bit Server VM (11.0.248-LTS, mixed mode, sharing, tiered, compressed oops, g1 gc, windows-amd64) 不知道为什么…...
C++拷贝构造函数与运算符重载应该注意的一个问题?
看下面的例子: class TestClass { public:char* _pdata;size_t _nLength;public:TestClass(const TestClass& other) {_nLength other._nLength;_pdata new char[_nLength];memcpy((void*)_pdata,other._pdata, _nLength 1);}TestClass(const char* pstr) {…...
[7] 游戏机项目说明
[7] 游戏机项目说明 在这节课中,我们将学习如何基于FreeRTOS开发一个简单的游戏项目。我们会使用一个开源项目nwatch,它是一个基于STM32的开源手表,包含了三个游戏。我们的目标是将这个游戏移植到我们的开发板上,并逐步使用FreeR…...
“深入浅出”系列之C++:(20)C++17
C17的新拓展 并行算法: C17引入了并行STL算法,允许使用多个线程并行处理元素,提高了在多核系统上的性能。 示例代码:std::sort(std::execution::par, v.begin(), v.end()); 类模板参数推导(CTAD)&#…...
.net一些知识点5
1.dot Net带out的参数如何使用 string name;//假设这个参数带out TestMethod(1,out name);//一定要有out 方法体中,一定要有out参数的赋值,并且能输出 2.参数的传递方式有哪些 a.值传递 b.引用传递 ref c.输出传递 out 3.设计模式知道哪些 3.us…...
(七)QT——消息事件机制&绘图&文件
目录 前言 消息事件机制 (Event System) 绘图 (Graphics & Drawing) 绘图设备 Qt 提供的主要绘图设备 Qt 主要绘图设备的特点 各个绘图设备的详细介绍 文件处理 (File Handling) 总结 前言 QT 是一个非常强大的图形用户界面(GUI)开发框架&…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
