欢迎光临
我们一直在努力

Kotlin Multiplatform day03

// ============================================
// 第 3 课:集合(List / Set / Map)+ 空安全(null)
// ============================================

fun main() {

// ========== 一、List:有序的列表(最常用)==========
// listOf 创建一个“只读”列表(不能增删改)
val fruits = listOf("苹果", "香蕉", "橙子")

println("水果列表:$fruits")
println("一共有 ${fruits.size} 种") // .size 是元素个数
println("第一个是 ${fruits[0]}") // 用 [下标] 取元素,下标从 0 开始!
println("最后一个是 ${fruits.last()}")

// 遍历列表
print("挨个打印:")
for (fruit in fruits) print("$fruit ")
println()

// 想要能“增删改”的列表,用 mutableListOf
val numbers = mutableListOf(1, 2, 3)
numbers.add(4) // 添加
numbers.remove(2) // 删除元素 2
numbers[0] = 100 // 修改第 0 个
println("可变列表操作后:$numbers")

// ========== 二、集合的“函数式”操作(超好用)==========
val scores = listOf(50, 88, 92, 71, 45)

// filter:筛选出满足条件的元素(这里筛及格的)
val passed = scores.filter { it >= 60 } // it 代表“当前这个元素”
println("及格的分数:$passed")

// map:把每个元素“变换”成新的值(这里每个分数 +5)
val bonus = scores.map { it + 5 }
println("每人加5分:$bonus")

// 还能链式组合:先筛及格,再看有几个
println("及格人数:${scores.filter { it >= 60 }.size}")

// 一些常用统计
println("总分=${scores.sum()}, 最高=${scores.max()}, 平均=${scores.average()}")

// ========== 三、Map:键值对(像字典:名字 -> 电话)==========
val phoneBook = mapOf(
"小明" to "138xxxx",
"小红" to "139xxxx"
)
println("小明的电话:${phoneBook["小明"]}") // 用 [键] 取值

// 遍历 Map
for ((name, phone) in phoneBook) {
println("$name 的号码是 $phone")
}

// ========== 四、空安全 null(Kotlin 的招牌特性)==========
// 在很多语言里,变量没值时是 null,一不小心访问就崩溃(著名的“空指针异常”)。
// Kotlin 从语法层面帮你防住这个问题。

// 默认情况下,变量【不允许】为 null:
val city: String = "北京"
// val bad: String = null // ← 这行会直接编译报错,不允许!

// 如果确实可能为空,要在类型后面加 ? 表示“可空”
// 这里从下面的 findNickname 函数拿昵称,它可能返回名字,也可能返回 null
val nickname: String? = findNickname(id = 99) // 传个查不到的 id,会得到 null

// 对可空变量,不能直接用,否则编译器不让过。要用下面几种安全方式:

// (1) 安全调用 ?. —— 如果是 null 就不执行,直接返回 null
println("昵称长度:${nickname?.length}") // nickname 是 null,所以打印 null

// (2) Elvis 运算符 ?: —— “如果左边是 null,就用右边的默认值”
val len = nickname?.length ?: 0
println("昵称长度(为空则算0):$len")

val show = nickname ?: "匿名用户"
println("显示名:$show")

// (3) 先判断再使用(判断后编译器就知道它不是 null 了)
val nickname2 = findNickname(id = 1) // 这次能查到
if (nickname2 != null) {
// 进到这里,编译器已确定 nickname2 不是 null,可以放心用 .length
println("昵称有值:$nickname2,长度 ${nickname2.length}")
} else {
println("昵称是空的")
}

// 综合示范:从通讯录查一个不存在的人
val unknown = phoneBook["路人甲"] // 查不到,返回 null
println("路人甲的电话:${unknown ?: "查无此人"}")
}

// 一个返回“可空类型 String?”的函数:id 为 1 时返回名字,否则返回 null
fun findNickname(id: Int): String? {
return if (id == 1) "小明" else null
}

全部跑通 🎉 结果都对(注意看可变列表那行:[1,2,3] → 加 4、删掉元素 2、把第 0 个改成 100 → 最终 [100, 3, 4]):

水果列表:[苹果, 香蕉, 橙子]

及格的分数:[88, 92, 71]

每人加5分:[55, 93, 97, 76, 50]

总分=346, 最高=92, 平均=69.2

昵称长度:null

显示名:匿名用户

路人甲的电话:查无此人


第 3 课知识点复盘

一、List(列表)—— 有序的一串数据

操作写法说明

创建只读列表

listOf("a","b")

不能增删改

创建可变列表

mutableListOf(1,2)

能 add / remove / 改

取元素

list[0]

下标从 0 开始(第一个是 0 号!)

个数

list.size

遍历

for (x in list) { }

⚠️ 新手最容易踩的坑:下标从 0 开始。3 个元素的下标是 0、1、2,没有 list[3](会崩溃)。

二、函数式操作 —— Kotlin 的精华 ✨

这是让代码变优雅的关键,日后写业务逻辑天天用:

scores.filter { it >= 60 } // 筛选:留下满足条件的

scores.map { it + 5 } // 变换:把每个元素改成新值

  • { … } 是一小段处理逻辑(叫 lambda,后面会专门讲)
  • it 是关键字,代表"当前正在处理的这个元素"
  • 还能链式连起来:scores.filter{…}.map{…}.sum()

三、Map(映射)—— 键值对,像字典

val m = mapOf("小明" to "138xxxx") // "键" to "值"

m["小明"] // 用键取值

for ((k, v) in m) { } // 同时拿到键和值

四、空安全 —— Kotlin 的招牌 🛡️

这是 Kotlin 相比很多老语言最大的优势之一,专门防止"空指针崩溃"。

语法名字作用

String

不可空

默认不允许是 null

String?

可空

加 ? 才允许为 null

a?.length

安全调用

a 是 null 就返回 null,不崩溃

a ?: 默认值

Elvis 运算符

a 是 null 就用右边的默认值

if (a != null) {…}

判空

判断后编译器就允许直接用 a

对照输出理解:

  • nickname 是 null → nickname?.length 打印 null(安全调用没崩)
  • nickname ?: "匿名用户" → 因为是 null,用了默认值 匿名用户
  • nickname2 查到了"小明" → 判空后能安全访问 .length,得到 2

💡 为什么这么重要?在 Java、C 等语言里,几乎所有 App 崩溃的头号原因就是"空指针"。Kotlin 用 ? 从编译阶段就逼你处理好,让 App 更稳定。这也是 Google 推荐用 Kotlin 写安卓的重要原因。


小练习 ✍️

给你个综合题(可以让我帮你跑):

有一个列表 val ages = listOf(15, 22, 17, 30, 8),用 filter 筛选出所有成年人(≥18),并打印出成年人的数量。

赞(0)
未经允许不得转载:171主机测评 » Kotlin Multiplatform day03
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址