2-2-8 快速掌握Kotlin-vararg关键字与get函数

🌟 Kotlin的vararg关键字与get函数:完美组合!

嘿!看到你对Kotlin的vararg关键字和get函数感兴趣,太棒了!这两个特性组合起来能让你的代码既灵活又优雅,就像给你的代码装上了"万能插头"一样!😄

🧩 vararg关键字:让参数数量"自由"起来

vararg (variable number of arguments)是Kotlin中用于定义可变数量参数的关键字,它允许函数接收任意数量的同类型参数。

基本用法

kotlin 复制代码
fun sum(vararg numbers: Int): Int {
    var total = 0
    for (num in numbers) {
        total += num
    }
    return total
}

// 调用示例
println(sum(1, 2, 3))       // 6
println(sum(1, 2, 3, 4, 5)) // 15
println(sum())              // 0(0个参数)

重要提示

  • vararg参数必须是最后一个参数
  • 不能将数组直接传递给vararg参数(会报类型不匹配错误)
  • 如果需要传递数组,可以使用*操作符

🧩 get函数:属性访问与数组索引

get函数在Kotlin中通常用于:

  1. 属性的getter(访问属性值)
  2. 重载[]运算符,实现类似数组的索引访问

基本用法

kotlin 复制代码
// 属性的getter
class Person {
    var name: String = "John"
        get() {
            println("Getting name: $field")
            return field
        }
}

// 重载[]运算符
class MyList<T>(vararg items: T) {
    private val list = items.toList()
    
    operator fun get(index: Int): T {
        return list[index]
    }
}

fun main() {
    val list = MyList(1, 2, 3, 4)
    println(list[2]) // 3
}

🔥 vararg与get函数的完美结合

现在,让我们看看它们如何组合使用,打造一个"万能士兵"类:

实战示例

kotlin 复制代码
class Soldier<T : Weapon>(vararg _items: T) {
    var items: Array<out T> = _items
    
    // 重载[]运算符,实现通过索引获取武器
    operator fun get(index: Int): T? {
        return items[index]
    }
    
    fun fight() {
        for (item in items) {
            item.fire()
        }
    }
}

open class Weapon(var name: String) {
    open fun fire() {
        println("Weapon fire!")
    }
}

class AK47 : Weapon("AK47") {
    override fun fire() {
        super.fire()
        println("AK47 fire fire!")
    }
}

class T72 : Weapon("T72") {
    override fun fire() {
        super.fire()
        println("T72 fire fire!")
    }
}

fun main() {
    val soldier = Soldier(AK47(), T72())
    soldier.fight()
    
    // 通过get获取特定武器
    println("First weapon: ${soldier[0]?.name}")
    println("Second weapon: ${soldier[1]?.name}")
}

执行结果

sql 复制代码
Weapon fire!
AK47 fire fire!
Weapon fire!
T72 fire fire!
First weapon: AK47
Second weapon: T72

💡 为什么这样组合这么强大?

  1. 灵活性 :vararg允许你传递任意数量的武器
  2. 便捷性 :get函数让你能像数组一样通过索引获取武器
  3. 类型安全 :通过泛型<T : Weapon>确保只能添加武器类型

🌟 实际应用场景

1. 通用数据结构

kotlin 复制代码
class DataContainer<T>(vararg items: T) {
    private val data = items.toList()
    
    operator fun get(index: Int): T {
        return data[index]
    }
    
    fun size(): Int {
        return data.size
    }
}

fun main() {
    val container = DataContainer("Apple", "Banana", "Cherry")
    println(container[0]) // Apple
    println(container.size()) // 3
}

2. 网络请求参数

kotlin 复制代码
fun fetchUrl(vararg urls: String) {
    // 处理多个URL
    urls.forEach { url ->
        println("Fetching $url")
    }
}

// 使用示例
fetchUrl("https://example.com", "https://example.org", "https://example.net")

3. 日志记录

kotlin 复制代码
fun log(vararg messages: String) {
    messages.forEach { message ->
        println("LOG: $message")
    }
}

// 使用示例
log("User logged in", "Session created", "Data loaded")

📌 重要注意事项

  1. vararg必须是最后一个参数:

    kotlin 复制代码
    // 正确
    fun process(a: Int, vararg b: String)
    
    // 错误
    fun process(vararg a: String, b: Int) // 编译错误
  2. 不能直接传递数组:

    kotlin 复制代码
    val array = arrayOf("a", "b", "c")
    // 下面代码会报错:Type mismatch: inferred type is Array<String> but String was expected
    process(array)
    
    // 正确做法:使用*操作符
    process(*array)
  3. get函数必须使用operator关键字:

    kotlin 复制代码
    operator fun get(index: Int): T { ... } // 必须加operator

💡 小贴士

  1. 命名约定 :vararg参数通常使用items、values、numbers等描述性名称
  2. 类型推断:Kotlin会自动推断vararg参数的类型
  3. 性能考虑:vararg在内部会创建一个数组,对于大量数据可能有性能开销
  4. 替代方案:如果需要频繁使用,考虑使用集合类型(如List)代替vararg

🌈 一个有趣的练习

试试看,写一个ShoppingCart类,它能存储任意数量的商品,并通过get函数按索引获取:

kotlin 复制代码
class ShoppingCart<T>(vararg items: T) {
    private val itemsList = items.toList()
    
    operator fun get(index: Int): T {
        return itemsList[index]
    }
    
    fun add(item: T) {
        // 实际实现会添加到列表
        println("Added $item to cart")
    }
}

fun main() {
    val cart = ShoppingCart("Apple", "Banana", "Cherry")
    println("First item: ${cart[0]}")
    cart.add("Mango")
}

📚 总结

  • vararg:让函数接收任意数量的同类型参数
  • get:重载[]运算符,实现类似数组的索引访问
  • 组合使用 :通过operator fun get,可以像访问数组一样通过索引获取vararg参数

这种组合让Kotlin的代码既灵活又安全,是Kotlin语言中非常优雅的特性之一!你学会了吗?😊

需要我帮你解决什么实际问题,或者想了解更多Kotlin的高级特性吗?我很乐意继续和你探讨!

相关推荐
三少爷的鞋32 分钟前
现代 Android 架构指南:不要再主动设计 Callback 接口
android
TimeFine6 小时前
AI 编码工作流的设计
android·ai编程
骑着蜗牛撵大象3277 小时前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
山东孙燕姿9 小时前
设备台账重构:从一张表到三层模型
android·java·网络·低代码·重构·rxjava
蒸鱼Yuzheng10 小时前
移动端 CPU 调度分析:线程亲和性、大小核迁移与卡顿
android·perfetto·性能分析·线程优化·cpu调度
booboosui10 小时前
安卓唤醒词:12 维 MFCC 加 DTW,阈值 1.8
android
传奇开心果10 小时前
Compose Multiplatform 共享边界实战:架构契约、互操作同步与可回退设计
android·kotlin
事圆则缓10 小时前
从开机到首帧:Android 系统与应用启动流程源码分析
android
AI吃大瓜10 小时前
指针压力表读数4:Android实现指针压力表读数(可实时检测)
android·指针读数·指针压力表·压力表·压力表读数
fengci.11 小时前
CTF2刷题记录(困难部分)
android·开发语言·前端·学习·php