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

四、Kotlin 表达式

1. 常量 & 变量

1.1 可读写变量(var

var x = initValue // x 称为可读写变量

注意:当 var 声明的变量做成员属性时,默认提供 setter/getter 方法。

1.2 只读变量(val

val x = initValue // x 称为只读变量

注意:

  1. val 声明的变量做成员属性时,默认只提供 getter 方法。
  2. val 声明的变量做全局变量或局部变量时,相当于 Java 中被 final 修饰的常量。

1.3 常量(const val

const val x = initValue // x  称为常量

注意:

  1. const 修饰的常量只能定义在全局范围内。
  2. const 只能修饰基本类型的变量。
  3. const 修饰的变量的初始值只能是字面量。

1.4 常量引用

常量引用即:使用 val 声明的类类型的变量。

val p = Person("xiaoming") 

其中:

  1. Person 对象创建在堆区,变量 pval 修饰,是一个常用引用。
  2. 由于 p 是常用引用,所以不能修改 p 的指向,但可以修改 p 对象中的成员。

2. if-else 表达式

Javaif-else 只是一个语句,对应一个三目运算符 “?:” 构成的条件表达式 express ? statement1 : statement2

Kotlinif-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 既可以作为语句,也可以作为表达式:

  1. 作为 try-catch 语句时,用法基本同 Java 一样:

    try {c = a/b
    } catch (e: Exception) { // Kotlin中的参数声明一般是 "参数名: 参数类型", Java中则是 "参数类型 参数名"e.printStackTrace()c = 0
    }
    
  2. 作为 try-catch 表达式时,最后一条执行语句的结果作为返回结果值:

    c = try {a/b
    } catch (e: Exception) {e.printStackTrace()0
    }
    

5. 运算符重载

Kotlin 官方文档:https://kotlinlang.org/docs/operator-overloading.html

可重载的运算符仅限 Kotlin 官方文档中指定的运算符。

5.1 运算符重载函数定义

  1. 运算符重载函数定义时需要加关键字 operator

  2. 运算符重载函数可以是:全局函数、或成员方法、或扩展方法

  3. 子类重写父类的运算符重载函数时,可以省略关键字 operator

5.2 运算符和运算符重载函数的对应关系

  1. == 对应 equals

    "str1" == "str2"  <==>  "str1".equals("str2")
    
  2. + 对应 plus

    a + b  <==>  a.plus(b)
    
  3. in 对应 contains

    element in list  <==>  list.contains(element)
    
  4. [] 对应 get

    val value = map[key]  <==>  val value = map.get(key)
    
  5. [] 对应 set

    map[key] = value  <==>  map.set(key, value)
    
  6. > 对应 compareTo

    a > b  <==>  a.compareTo(b) > 0  // <, >=, <= 与之类似
    
  7. () 对应 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 表达式与函数式接口的关系
  1. Java 中的 Lambda 表达式就是用来代替用于创建函数式接口对象的匿名内部类
  2. Java 中的 Lambda 表达式其实就是函数式接口的抽象方法的匿名函数实现
  3. Java 中的 Lambda 表达式的结果值就是一个函数式接口的实例对象

总的来说:Java 中的 Lambda 表达式其实就是一个匿名函数,这个匿名函数就是函数式接口的抽象方法。也就是说,Java 中的 Lambda 表达式就是在重写函数式接口的抽象方法。但是整个 Lambda 表达式的结果值,并不是函数式接口的抽象方法返回值,而是一个函数式接口的实例对象。

9.1.3 Java 中的 Lambda 表达式的使用场景
  1. Lambda 表达式赋给函数式接口类型的变量;

  2. Lambda 表达式作为函数式接口类型参数的实参;

  3. Lambda 表达式强制转换为函数式接口类型。

9.1.4 Java 中的 Lambda 表达式的语法
(T1 p1, T2 p2, ...) -> {...}  // 不需要显示指定返回值类型

特别地:

  1. 考虑到 Lambda 表达式的使用场景,总能确定 Lambda 表达式对应的函数式接口,所以可以省略 Lambda 表达式的形参列表中的参数类型,即:

    (T1 p1, T2 p2, ...) -> {...}   <==>  (p1, p2, ...) -> {...}
    
  2. 当形参列表只有一个参数时,可以省略括号 “()”,即:

    p1 -> {...}
    
  3. 当形参列表没有参数时,不可以省略括号 “()”,即:

    () -> {...}
    
  4. Lambda 表达式中的函数体只有一条语句时,可以省略花括号 “{}”,即:

    (T1 p1, T2 p2, ...) -> statement
    

9.2 Kotlin 中的 Lambda 表达式

9.2.1 语法
{p1: T1, p2: T2, ... -> statement1statement2...statementN
}

注意:

  1. 以上 Lambda 表达式对应一个函数类型为 (T1, T2, ...) -> ReturnType 的匿名函数。其中 ReturnType 由最后一条执行语句 statementN 的结果值确定。若 statementN 没有结果值,则 ReturnTypeUnit

  2. KotlinLambda 表达式的结果值是一个函数引用,所以可以将 Lambda 表达式赋给函数类型为 (T1, T2, ...) -> ReturnType 的变量。

  3. 当显示指定了变量的函数类型时,Lambda 表达式的形参列表中的参数类型可以省略,如:

    val funRef: (T1, T2, ...) -> ReturnType = {p1, p2, ... ->statement1statement2...statementN // 最后一条语句的结果值必须是ReturnType
    }
    
  4. 当形参列表为空时,可以省略 “p1: T1, p2: T2, ... ->”,如:

    val funRef: () -> ReturnType = {statement1statement2...statementN
    }
    
  5. 当形参列表只有一个参数时,可以使用默认参数 it

    val funRef: (T1) -> ReturnType = {// 虽然没有声明形参列表,但存在一个 T1 类型的默认参数 it
    }
    
  6. 当存在一个函数,且函数形参列表的最后一个形参是函数类型,若调用该函数时,使用 Lambda 表达式作为最后一个函数类型形参的实参,则 Lambda 表达式可以写在函数调用运算符 “()” 的后面。

    特别地,当函数的形参列表只是一个函数类型的参数时,还可以省略函数调用运算符 “()

9.2.2 Kotlin 中的 Lambda 表达式 & Java 中的 Lambda 表达式的区别

Java 中的 Lambda 表达式的结果值是一个函数式接口的实例对象。

Kotlin 中的 Lambda 表达式的结果值是一个匿名函数的函数引用。

JavaLambda 表达式:

Runnable runable = () -> {// Java 的 Lambda表达式就是在重写 Runnable 接口的 run 方法...
}

KotlinLambda 表达式:

val funRef = {// Kotlin 的 Lambda 表达式就是一个匿名函数...
}

相关文章:

四、Kotlin 表达式

1. 常量 & 变量 1.1 可读写变量&#xff08;var&#xff09; var x initValue // x 称为可读写变量注意&#xff1a;当 var 声明的变量做成员属性时&#xff0c;默认提供 setter/getter 方法。 1.2 只读变量&#xff08;val&#xff09; val x initValue // x 称为只…...

Web开发4:单元测试

在Web开发中&#xff0c;单元测试是一种重要的开发实践&#xff0c;它可以帮助我们确保代码的质量和可靠性。通过编写和运行单元测试&#xff0c;我们可以验证代码的正确性&#xff0c;减少错误和缺陷&#xff0c;并提高代码的可维护性。本文将介绍单元测试的概念、好处以及如何…...

Ubuntu 16 让ufw防火墙控制docker容器中所有端口

使用docker ps 查询docker在运行端口。 rootai-0003:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS …...

<蓝桥杯软件赛>零基础备赛20周--第18周--动态规划初步

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…...

vb如何获取鼠标形状的特征码

vb如何获取鼠标形状的特征码 好像按键精灵有一个GetCursorShape()函数可以获取特征码&#xff0c;不知道VB6能不能实现类似的功能&#xff1f; 附注&#xff1a; 1 最好是机器无关的&#xff0c;不是也可以。 2 特征码就是一串数字&#xff0c;用来区分不同的鼠标形状。 3 获取…...

chroot: failed to run command ‘/bin/bash’: No such file or directory

1. 问题描述及原因分析 在busybox的环境下&#xff0c;执行 cd rootfs chroot .报错如下&#xff1a; chroot: failed to run command ‘/bin/bash’: No such file or directory根据报错应该rootfs文件系统中缺少/bin/bash&#xff0c;进入查看确实默认是sh&#xff0c;换成…...

蓝桥杯备战——2.矩阵键盘

1.分析原理图 由上图可以看到若J5跳线帽接地&#xff0c;就S4~S7就可以当做四路独立按键&#xff0c;若接到P44&#xff0c;则就是4*4的矩阵键盘。 2.独立按键处理 相对传统的按键延时消抖方案&#xff0c;这里我采用更高效&#xff0c;更经典&#xff0c;更偏向产品级应用的…...

Docker部署思维导图工具SimpleMindMap并实现公网远程访问

文章目录 1. Docker一键部署思维导图2. 本地访问测试3. Linux安装Cpolar4. 配置公网地址5. 远程访问思维导图6. 固定Cpolar公网地址7. 固定地址访问 SimpleMindMap 是一个可私有部署的web思维导图工具。它提供了丰富的功能和特性&#xff0c;包含插件化架构、多种结构类型&…...

机器学习实验2——线性回归求解加州房价问题

文章目录 &#x1f9e1;&#x1f9e1;实验内容&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;数据预处理&#x1f9e1;&#x1f9e1;代码缺失值处理特征探索相关性分析文本数据标签编码数值型数据标准化划分数据集 &#x1f9e1;&#x1f9e1;线性回归&#x1f9e1;&am…...

宝塔+nextcloud+docker+Onlyoffice 全开启https

折腾了我三天的经验分享 1.宝塔创建网站 nextcloud版本为28.0.1 php8.2 &#xff0c;导入nextcloud绑定域名对应的证书 &#xff0c;不用创建mysql 因为nextcloud 要求是mariadb:10.7 宝塔里没有&#xff0c;就用docker安装一个 端口设置为3307 将数据库文件映射出来/ww…...

呼吸机电机控制主控MCU方案

呼吸机是一种能代替、控制或改变人的正常生理呼吸&#xff0c;增加肺通气量&#xff0c;改善呼吸功能&#xff0c;减轻呼吸功消耗&#xff0c;节约心脏储备能力的装置。呼吸机连接一条管子到患者的嘴或鼻子&#xff0c;氧气量可以通过监视器加以控制。 基于灵动微控制器的呼吸…...

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面试题合集-基础

前言 又来到每日的复习时刻&#xff0c;昨天我们学习了mysql相关基础知识&#xff0c;还有分布式数据库介绍&#xff08;后续总结时再持续更新&#xff09;。今日继续学习缓存杀器&#xff1a;redis redis基础面试题合集 什么是Redis&#xff1f; Redis是一个开源的、内存中…...

(Unity)C# 中的字符串格式化

前言 在软件开发中&#xff0c;理解和掌握字符串的格式化及调试技巧对于编写高效和可维护的代码至关重要。 字符串插值 ($ 符号) 在 C# 中&#xff0c;字符串插值是通过在字符串前加 $ 符号来实现的。这允许我们将变量、表达式或函数调用直接嵌入到字符串中。 string name &qu…...

【项目日记(五)】第二层: 中心缓存的具体实现(上)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…...

使用PSIM软件生成DSP28335流水灯程序

最近在学习DSP28335芯片&#xff0c;然后在使用PSIM仿真软件时发现这个仿真软件也支持28335芯片&#xff0c;于是就想学习下如何在PSIM软件中使用DSP28335芯片。在PSIM自带的官方示例中有使用DSP28335芯片的相关例子。 工程下载链接 https://download.csdn.net/download/qq_20…...

【iOS ARKit】人脸检测追踪基础

在计算机人工智能&#xff08;Artificial Inteligence,AI&#xff09;物体检测识别领域&#xff0c;最先研究的是人脸检测识别&#xff0c;目前技术发展最成熟的也是人脸检测识别。人脸检测识别已经广泛应用于安防、机场、车站、闸机、人流控制、安全支付等众多社会领域&#x…...

ES的一些名称和概念总结

概念 先看看ElasticSearch的整体架构&#xff1a; 一个 ES Index 在集群模式下&#xff0c;有多个 Node &#xff08;节点&#xff09;组成。每个节点就是 ES 的Instance (实例)。每个节点上会有多个 shard &#xff08;分片&#xff09;&#xff0c; P1 P2 是主分片, R1 R2…...

Javaweb之SpringBootWeb案例之阿里云OSS服务集成的详细解析

2.3.3 集成 阿里云oss对象存储服务的准备工作以及入门程序我们都已经完成了&#xff0c;接下来我们就需要在案例当中集成oss对象存储服务&#xff0c;来存储和管理案例中上传的图片。 在新增员工的时候&#xff0c;上传员工的图像&#xff0c;而之所以需要上传员工的图像&…...

【GitHub项目推荐--不错的 Go 学习项目】【转载】

开源实时性能分析平台 Pyroscope 是基于 Go 的开源实时性能分析平台&#xff0c;在源码中添加几行代码 pyroscope 就能帮你找出源代码中的性能问题和瓶颈、CPU 利用率过高的原因&#xff0c;调用树展示帮助你理解程序&#xff0c;支持 Go、Python、Ruby 语言。 Pyroscope 可以…...

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

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

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...