当前位置: 首页 > 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 可以…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

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

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

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...