Kotlin 笔记

Kotlin 笔记

原创 已于 2026-09-02 14:39:02 修改 · 粉丝可见 · 62 阅读 · 0 · 0 GEO检测 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/150225457

目录

[TOC]

简介

Kotlin是一种现代化的静态类型编程语言,具有以下优势:

  1. 与java互操作性强:Kotin 可以与现有的 Java 代码无缝地互操作,允许开发者在现有的项目中逐步采用 Kotin,而不需要重写整个项目。这使得 Kotlin 成为 Android 应用开发的理想选择。

  2. 简洁易读:Kotin 的语法简洁并具有更好的可读性,减少了样板代码的编写。相比 Java、Koti 可以使用更少的代码来实现同样的功能,从而提高开发效率。

  3. 空安全性:Kotin 对空值进行了更好的处理。在 Kotin 中,变量默认是非空的,如果需要使用可能为空的值,需要显式声明类型为可空。这有助于减少空指针异常的发生。

  4. 函数式编程支持:Kotin 支持函数式编程的特性,如高阶函数、lambda 表达式和函数式编程的集合操作等。这些特性可以让开发者编写更简洁、可维护的代码,并提高代码的表达能力。

  5. 扩展函数:Kotin 允许开发者为某个类添加新的方法,而不需要修改该类的源代码。这种扩展函数的特性可以为开发者提供更灵活的方式来扩展现有的类库。

  6. 协程支持:Kotin引入了协程(coroutine)机制,使得异步操作更易于管理和编写。通过使用协程,开发者可以使用顺序的方式编写并发代码,并避免了回调地狱的问题。

总的来说,Kotin 是一门功能丰富、可读性高、与 Java 无缝互操作的编程语言,适用于 Android、Web 后端开发等多种场景。

环境配置

简单通过 VMR 去安装也可以的,但是注意,安装路径中的目录不能有空格的目录名,否则会报错。

初级

入门尝试

简单尝试,保存为Main.kt  文件

1
2
3
fun main(){
println("Hello,world");
}

运行编译

1
kotlinc Main.kt -include-runtime -d Main.jar

多出一个 Main.jar,编译为了 jar 包。通过java运行

1
java -jar Main.jar

运行效果成功。

变量的声明与使用

变量声明

1
2
3
4
5
6
7
8
9
10
var [变量名称] : [数据类型] ;

// 或者赋予默认值

var [变量名称] : [数据类型] = [默认值] ;

// 或者默认自动推导类型

var number = 15

常量声明

1
2
3
4
5
6
val [变量名称] : [数据类型] = [默认值] ;

// 或者默认自动推导类型

val number = 15

数据类型

数字类型

对于一些比较长的数字,我们可能需要使用类似于分隔符一类的东西来方便我们计数。

银行往往把1000000000这种长数字记为1,000,000,000,这样看起来会更直观

在Kotlin中也可以像这样去编写:

1
val a = 1_000_000_000

数字类型不仅可以写成十进制,也可以是十六进制或是二进制表示( Kotlin不支持八进制表示

十六进制:

1
val a = 0xAF

二进制:

1
val a = 0b1001

除了整数类型外,Kotlin还为无符号整数提供以下类型:

  • UByte:一个无符号8位整数,范围从0到255

  • UShort:无符号16位整数,范围从0到65535

  • UInt:一个无符号32位整数,范围从0到2^32-1

  • ULong:一个无符号64位整数,范围从0到2^64-1

为了使无符号整数更易于使用,Kotin同样提供了用后缀标记,该后缀表示无符号类型(类似于上面的Long类型添加L字母)

1
2
3
4
5
val b:UByte =1u //UByte类型,由变量提供的类型
val s:UShort = 1u//UShort类型,由变量提供的类型
val 1:ULong =1u //ULong类型,由变量提供的类型
val a1 = 42u //UInt类型,根据数字大小自动推断得到
val a2= 0xFFFF_FFFF_FFFFu //ULong类型,根据数字大小自动推断得到

uL 和UL 可以将文字直接标记为无符号Long类型

1
val a=1UL  //ULong类型,直接使用后缀标记

浮点数

对于小数来说,Kotin提供符合 IEEE754 标准的浮点类型Float和 Double,Float 为 IEEE754 标准中的单精度数据,而Double位标准中的双精度数据,对于单双精度,本质上就是能够表示的小数位精度,双精度比单精度的小数精度更高。

数字类型的运算

简单的加减乘除就不详细赘述了。

Kotin提供了一组整数的位运算操作,可以直接在二进制层面上与数字表示的位进行操作,不过只适用于Int 和Long类型的数据:

  • shl(bits) - 有符号左移

  • shr(bits) - 有符号右移

  • ushr(bits) - 无符号右移

  • and(bits) - 按位与

  • or(bits) - 按位或

  • xor(bits) - 按位异或

  • inv() - 取反

布尔类型

布尔值除了可以直接赋值得到,也可以通过一些关系运算得到,常见的关系运算有大于、小于以及等于,所有的关系运算在下方:

  • 判断两个数是否相等:a==b 和 a!=b

  • 判断数之间大小:a<b,a>b,a<=b,a>=b

  • 判断数是否在指定范围中:a..b,x in a..b,x !in a..b

字符类型

字符类型的作用与 C语言的 字符类型一致,也可以表示 ASCII 码。

字符串类型

这里的字符串类型与 python 有点像。

可以使用 三个双引号 打印多行文本

1
2
3
4
5
6
7
8
9
10
11
12
package com.angindem


fun main() {
val tem : String =
"""
Hello,
World!
""";

println(tem);
}

模板表达式

通过 `$` 取值嵌入字符串中。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.angindem


fun main() {
val name : String = "Angindem";
val age : Int = 20;
val tem : String =
"""
Hello, I am ${name} and I am ${age} years old.
World!
""";

println(tem);
}

模板表达式中也可以写入表达式,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.angindem


fun main() {
val name : String = "Angindem";
val age : Int = 20;
val sex : String = "Male";
val tem : String =
"""
Hello, I am ${name} and I am ${age} years old.
World! I am ${
if (sex.equals("Male")){
"Boy"
} else {
"Girl"
}
} Student.
""";

println(tem);
}

如果用到特殊符号记得转义字符。

if-else判断分支

对于这个与Java基本一致。多了一个特性,可以在变量中进行分支判断。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.angindem


fun main() {
val name : String = "Angindem";
val age : Int = 20;
val grad : String = if (age > 18) "Graduate" else "Student";
val sex : String = "Male";
val tem : String =
"""
Hello, I am ${name} and I am ${age} years old.
World! I am ${
if (sex.equals("Male")){
"Boy"
} else {
"Girl"
}
} ${grad} Student.
""";

println(tem);
}

when选择分支

它的作用类似Java和C语言中的 switch。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.angindem


fun main() {
val name : String = "Angindem";
val age : Int = 20;
val grad : String = if (age > 18) "Graduate" else "Student";
val sex : String = "Male";
val score: Int = 80;
// var nickName : String;
// when (score) {
// 100 -> nickName = "Perfect"
// in 90..99 -> nickName = "Excellent"
// in 80..89 -> nickName = "Good"
// in 70..79 -> nickName = "Average"
// else -> nickName = "Poor"
// }
val nickName : String = when (score) {
100 -> "Perfect"
in 90..99 -> "Excellent"
in 80..89 -> "Good"
in 70..79 -> "Average"
else -> "Poor"
}
val tem : String =
"""
Hello, I am ${name} and I am ${age} years old.
World! I am ${
if (sex.equals("Male")){
"Boy"
} else {
"Girl"
}
} ${grad} Student. my score is ${nickName}.
""";

println(tem);
}

for循环

for循环和Java、C语言基本一致。多了以下写法:

1
for(遍历出来的单个目标变量 in 可遍历目标)循环体

这里的可遍历目标有很多,比如:

  • 数组

  • 区间(Range,示例:val range : IntRange = 1..10;)

  • 任何实现了运算符重载函数iterator的类

示例代码:

1
2
3
4
5
6
7
8
9
10
package com.angindem


fun main() {
val range : IntRange = 2..5; // [2,3,4,5]

for(i in range){
println("我执行了 ${i} 次,说 Hello World!!!")
}
}

默认情况下,每一轮循环会向后 +1 , 我们也可以自由控制每一轮增加多少,也就是步长:

1
2
3
4
5
6
7
8
9
package com.angindem

fun main() {
val range : IntRange = 1..5; // [2,3,4,5]

for(i in range step 2){
println("我执行了 ${i} 次,说 Hello World!!!")
}
}

也可以倒着遍历,将 `...` 替换成 downTo, 示例:

1
2
3
4
5
6
7
package com.angindem

fun main() {
for(i in 10 downTo 1 step 2){
println("我执行了 ${i} 次,说 Hello World!!!")
}
}

标签语句 `@`

类似于 C语言的 goto。不同的是仅限于循环嵌套进行循环的别名,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.angindem

fun main() {

for (a in 1..5) {

println("@ 标签的使用前提是要有最外层循环,它相当于给某一层循环起了一个别名,通过 continue、break、return 表示这个别名的循环执行continue或者break或者return")

tz@ for (b in 1..5) {
for (c in 1..5) {
for (d in 1..5) {
if (d == 2) {
break@tz
}
println("a = $a, b = $b, c = $c, d = $d")
}
}
}
}
}

while循环

while循环和C语言基本一致,也有 do while 循环。

中级

函数

kotlin中万物皆函数。

Kotlin 函数使用 fun关键字声明:

1
2
3
fun 函数名称([函数参数...]): 返回值类型{

}

简单示例:

1
2
3
4
5
6
7
8
9
10
package com.angindem

fun test(){
println("A")
println("B")
}

fun main() {
test();
}

默认值

函数默认值和C语言的差不多,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.angindem

fun test(a:Int = 20,b: Int,c:Int = 20):Int{

println("a = $a, b = $b, c = $c")
val sum :Int = a + b + c;
println("a + b + c = ${sum}")
return sum;
}

fun main() {

val sum = test(b = 10);
println("sum = $sum")
}

函数内部也可以进行定义函数。也支持函数重载:函数名相同,参数不同。

变量

之前说过,万物皆函数,这里的变量就是如此了。我们正常的进行获值和赋值就是调用变量中的 get、set。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.angindem

var a: Int = 10
set(value) {
println("Setting value for a")
field = value
}
get() {
println("Getting value for a")
return field
}

fun main() {
a = 20
println(a)

}

注意:Kotlin 里 get / set 是紧贴在属性声明后面的访问器,它必须和属性声明连成一体。而分号 会强制终结当前声明!

递归函数

有关递归函数,基本是老生常谈了。基本概念那些我就不做过多介绍。

对于 Kotlin ,有一个关键字可以将尾部作为返回值进行递归的操作优化: tailrec

示例:

1
2
3
4
5
6
7
8
9
10
package com.angindem


tailrec fun fbn(n: Int,sum:Int = 0): Int {
return if (n <= 0) sum else fbn(n - 1, sum + n)
}

fun main() {
println(fbn(5))
}

实际上在编译之后,大概会变成:

1
2
3
4
5
6
7
8
public static final int fbn(int ,int prev){
while( n > 0 ){
int var2 = n - 1;
n = var2;
.......
}
return 0
}

实用库函数

标准输入输出

readln

输入整行

运算函数

pow()

abs()

max()

函数型变量

有点类似 C++ 的回调函数。

也类似  JavaScript 中的 lambda 表达式的箭头函数声明

简单示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.angindem

fun test(num: Int, backFun:(Int)-> Int): Int{
var ans = num + backFun(num)
println("ans = $ans")
return ans;
}


fun main() {
fun copeNum(num: Int): Int{
return num + 10;
}

test(10, ::copeNum);
}


搞清楚”函数型变量”到底在说什么

以前学的变量,存的是数据:

1
2
3
val age = 18 // 存了一个"结果"

val name = "小明" // 存了一个"值"

而函数型变量,存的是行为——也就是”一段还没执行的代码”。

打个比方:

🍳 普通变量 = 一盘做好的菜(结果现成,拿来就能吃)

🍲 函数型变量 = 一张菜谱(存的不是菜,是”怎么做”的步骤。你得照着步骤执行,才会做出菜来)

这是最关键的一点,理解了它,后面全通了。看这个对比:

1
2
3
val x = 1 + 1 // 立刻算出 2,x 存的是"结果 2"

val f = { 1 + 1 } // 不计算!f 存的是"一段代码",直到调用 f() 才算

可以这样理解: f 就像存了一个”按钮”,只有按下按钮(调用 f() ),里面的代码才真正执行。

对于调用函数型变量

  • :: 后:局部函数、顶层函数都能正常传参 ✅(输出 30120

  • 不加 :: :哪怕是顶层函数,也报一模一样的错 ❌

所以问题不在你的代码结构,而在于一个 Kotlin 的语法规则。

核心规律:为什么 lambda 能直接传,具名函数要加 ` :: ` ?

写法 它的本质 能不能直接当值传?
{ n -> n + 1 } (lambda) 本身就是一个函数值 ✅ 直接传
fun(a: Int, b: Int): Int = a * b (匿名函数) 本身就是一个函数值 ✅ 直接传
addOne (存了 lambda 的变量) 变量=值 ✅ 直接传
copeNum / topFun (具名函数) 是一个”名字”,不是值 ❌ 必须 ::copeNum

` :: `的作用一句话:把”函数的名字”变成”函数的数值”。

再打个比方——你去饭店:

🍽️ 你喊”宫保鸡丁”,服务员以为你要点这道菜(= 调用这个函数)。 你要是说”给我一份宫保鸡丁的菜谱”,才是在要”做法本身”(= 把这个函数当值)。 :: 就是那个”菜谱”按钮。直接写函数名,Kotlin 会以为你想调用它,所以报错说 function invocation 'copeNum(...)' expected (”你这里是不是想调用 copeNum(...)?”)。

匿名函数(习惯 return 就用这个)

1
2
3
var addOne: (Int) -> Int = fun(n: Int): Int {
return n + 1 // 匿名函数是"真正的函数",可以用 return
}

起别名关键字typealias

这里的 typealias 和 C语言的 typedef 和 #define 基本类似。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
package com.angindem

typealias Test = String;


fun main() {

var str: Test = readln();

println("str = $str")
}

lambda表达式与高阶函数

lambda表达式

1
2
3
4
5
6
7
8
9
10
11
12
package com.angindem

fun test(a: Int, backFun:(Int)-> Unit){
backFun(a)
}

fun main() {
test(10,{
a->
println("num = $a")
})
}

多行lambda函数型变量(多条逻辑,最后一行是返回值)

(多条逻辑,最后一行是返回值)

1
2
3
4
5
6
var addOne: (Int) -> Int = { n ->
println("开始处理 n = $n") // 第一行逻辑
val temp = n + 1 // 第二行逻辑
println("处理完毕")
temp // 最后一行 = 返回值,不写 return
}

如果函数调用的尾随 lambda表达式默认的标签名字就是函数名字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.angindem

fun test(fundemo:(String)-> String){
println(fundemo("我大于5,使用标签返回"))
println(fundemo("1"))
}

fun main() {

test{
str->
if (str.length > 5) return@test str
else "我小于5,不用标签返回"
}

}

内联函数

inline 关键字,与 C++ 的内联函数效果一样。进行性能的优化,将原本包裹的函数,直接提取变成源代码,而不是以函数的形式。所以一般递归函数不建议使用内联关键字

这里需要注意的一点,内联函数中参数是函数型变量,则需要noinline关键字。示例:

1
2
3
4
5
6
7
8
9
10
11
package com.angindem

inline fun test(noinline func:(String)-> Unit){
val a = func
println("这是一个内联函数")
a("HelloWorld")
}

fun main() {
test { "打印 $it" }
}

为什么需要 noinline

关键在于理解 inline 的本质:

inline = 编译器把你的函数体”抄写”到调用它的地方(展开)。 lambda 参数 func 也一样——它会被直接展开成一段代码,而不是变成一个”对象”。

可你写了 val a = func ——你想把 func 存起来。这就矛盾了:

  • inline 想让它变成”展开的代码” ✅

  • 存变量要求它是”一个能被存放的对象” ❌

一个东西不可能同时既是”展开的代码”又是”被存放的对象”。

所以编译器直接报错,并给你指路:加 noinline

noinline 做了什么?

noinline 就是告诉编译器:

“这个 func 参数我不要内联展开,你把它当成一个普通函数对象处理吧。”

这样它就可以被存进变量、传出、到处传递了。

打个比方:

📋 inline 的 lambda 像纸条上的话——调用时直接”念出来”(展开)。 而 val a = func 是想把纸条本身收进抽屉。 想收进抽屉,就得先把话从”活的声音”变成”实物纸条”——这就是 noinline 的切换。

一句话总结:

inline 想让 lambda”展开”省开销,代价是不能把它当对象存。 需要存放/传递 lambda 时,就加 noinline 放弃展开,换来”自由使用”。

内联高阶函数的lambda参数可以直接写 return 不指定标签

示例:

1
2
3
4
5
6
7
8
9
10
11
12
package com.angindem

inline fun test(func:()-> Unit){
println("我是test函数return之前,我有没有被打印")
func();
println("我是test函数return之后,我有没有被打印")
}

fun main() {
test { return }
println("我是main函数,我有没有被打印")
}

因为内联了,展开代码到main函数中了,这里的return相当于终结main函数。

类的定义

这里的类的定义和Java的类定义类似。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
package com.angindem.domain.po

class Student{
var name:String;
var age:Int;
constructor(name:String,age:Int){
this.name = name;
this.age = age;
}
constructor(name: String):this(name,15) // 构造函数重载
}

但是这里需要注意的是:

如果没有这个构造函数,类定义必须要有个初始值:

1
2
3
4
5
6
package com.angindem.domain.po

class Student{
var name:String = "";
var age: Int = 0;
}

Kotlin也有一个写法:

1
2
3
4
package com.angindem.domain.po

class Student(name:String,age:Int){
}

表示构造这个类,有点类似C++。

注意这里类的定义和Java不太一样,不太需要定义 get、set,因为本身已经做好了封装。如果对某个属性 get 以及set额外操作,自行操作定义的。

为什么不存在?—— Java 惯性思维在这里失灵了

你用 Java 的脑子在想: private 字段 → 手动写 getName() / setName() → 别人通过方法访问。这套在 Java 完全正确。

但 Kotlin 不是这么玩的。打个比方:

Java 的字段 Kotlin 的属性(property)
本质 字段是”保险柜里的钱”,方法是你手动开的”窗口” var name 是一个自带窗口的保险柜
你要取钱 必须走你手写的窗口 getName() 直接说 student.name ,窗口自动开

关键区别来了:

  • var name (不写 private) → Kotlin 自动给它配好”窗口”(getter/setter),外面直接 student.name 读写。

  • private var name → Kotlin 认为”这是柜主私藏的钱,连窗口都不装了”,外面既没有 student.name ,也没有 getName() ——彻底锁死。

所以你现在是:保险柜加了 private 锁死 → 却又想从”不存在的窗口”取钱(getName) → 当然找不到。

lateinit 关键字

这里是懒加载关键字,暂时先不初始化对象。示例:

1
2
3
4
5
6
package com.angindem.domain.po

class Student{
lateinit var name:String;
lateinit var age:Int; // 这里会报错,因为 lateinit 不能用于基本数据类型
}

对象的使用与创建

注意,Kotlin的对象创建与使用与 C++ 有点类似,和 Java的区别就是不需要new。

简单示例:

1
2
3
4
5
6
7
8
package com.angindem

import com.angindem.domain.po.Student

fun main() {
var student = Student( "张三",15)
println("学生姓名:${student.getName()},学生年龄:${student.getAge() }")
}

同时注意,这里的对象直接赋值,并不是复制一份对象,而是类似C语言的指针交换。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.angindem

import com.angindem.domain.po.Student

fun main() {
var student = Student( "张三",15)
var copyStudent = student;

copyStudent.name = "李四";

println("学生姓名:${student.name},学生年龄:${student.age }")

println("是不是同一个对象:${student === copyStudent}")

}

对象的初始化

init关键字,示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.angindem.domain.po

class Student{
var name:String;
var age:Int;
constructor(name:String,age:Int){
this.name = name;
this.age = age;
}
constructor(name: String):this(name,15)


init{
println("init block,我new出来了")
}
}

类的成员函数

这里的成员函数和C++的成员函数基本一致。

再谈基本类型

Kotlin中将基本类型也都封装成了对象类。

特别说明:在Kotin中,虽然编码时万物皆对象,但是在最终编译时,会根据上下文进行优化性能

大部分情况下会优先编译为Java原生基本数据类型(不是对象)

而另一部分情况下才会编译为Java中的Integer包装类型。因此很容易出现以下迷惑行为:

1
2
3
val a : Int = 123456
val b : Int = 123456
println(a === b) // true
1
2
3
val a : Int? = 123456
val b : Int? = 123456
println(a === b) // true

运算符重载

这里的运算符重载和 C++ 基本一致。示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.angindem.domain.po

class NumberObject{
var number: Int;
constructor(age: Int){
this.number = age
}

operator fun plus(other: NumberObject): NumberObject {
return NumberObject((this.number + other.number) * 2)
}

override fun toString(): String {
return this.number.toString()
}
}

运算:

1
2
3
4
5
6
7
8
9
package com.angindem

import com.angindem.domain.po.NumberObject

fun main() {
var num1:NumberObject = NumberObject(5);
var num2:NumberObject = NumberObject(5);
println(num1 + num2)
}

结果:

这里附带一下对应的函数名称:

符号 对应的函数名称
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.rem(b)
a..b a.rangeTo(b)
a in b b.contains(a)
a !in b !b.contains(a)
a[i] a.get(i)
a[i, j] a.get(i, j)
a[i_1, ..., i_N] a.get(i_1, ..., i_N)
a[i] = b a.set(i, b)
a[i, j] = b a.set(i, j, b)
a[i_1, ..., i_N] = b a.set(i_1, ..., i_N, b)
a == b a.equals(b)
a != b !a.equals(b)
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
a >= b a.compareTo(b) >= 0
a <= b a.compareTo(b) <= 0
a() a.invoke()
a(i) a.invoke(i)
a(i, j) a.invoke(i, j)
a(i_1, ..., i_N) a.invoke(i_1, ..., i_N)
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.remAssign(b)
a++ a.inc()
a-- a.dec()
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a && b a.and(b) (或 a && b 编译为逻辑与,但无对应函数,实际为短路运算)
a || b a.or(b) (同理短路运算)
a..<b a.rangeUntil(b) (Kotlin 1.7+)
a < b .. c 无直接函数,由 rangeTo 和 compareTo 组合

其中inc()和dec()函数比较特殊,它们必须返回一个值,该值将分配给使用++或--操作的变量,而不是改变执行inc或dec操作的对象,意思就是执行后应该得到一个新生成的对象,然后变量的值直接引用到这个新的对象,因为nt类型就是这样的,比如a++的操作步骤如下:

  • 将a的初始值存储到临时存储a0

  • 将a0.inc()的结果分配给a。

  • 返回a0作为表达式的结果。

同样的,++a的操作步骤如下:

  • 将a.inc()的结果分配给a。

  • 作为表达式的结果返回a的新值。


觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭

微信二维码

wechat pay

支付宝二维码

ali pay

Kotlin 笔记
http://blog.angindem.cn/2026/09/02/Angindem-CSDN博客/207_207/
作者
Angindem
发布于
2026年9月2日
许可协议