Koltin基础学第三章 函数的定义和调用

函数的定义和调用

3.1在kotlin中创建集合

创建不同的集合

val set = hashSetOf(1, 7, 5)
val list = arrayListOf(1, 7, 5)
//to是一个创建pair对象的关键字,<A,B>
val map = hashMapOf(1 to "one", 2 to "two", 3 to "three")
//inv是to的反向操作符,返回包含“apple”的第一个pair对象并与5组成新的pair对象
val originalPair: Pair<String, Int> = "apple" to 5
val reversedPair: Pair<Int, String> = originalPair.inv()

采用的是标准的java集合类,是为了方便与java代码交互
与之不同的是,kotin给集合新增了很多函数操作例如 last,max

 val last = list.last()
    val max = list.max()

3.2 让函数更加好用

实现 “,” 转“;”函数

fun <T> joinToString(
        collection: Collection<T>,
        separator: String,//开头
        prefix: String,//间隔符
        postfix: String//结尾
    ): String {
        val result = StringBuilder(prefix)

        for ((index, element) in collection.withIndex()) {
            if (index == 0) result.append(separator)
            result.append(element)
        }
        result.append(postfix)
        return result.toString()
    }

    val result = joinToString(list, "(", ";", ")")

命名参数

//命名参数 最好用IDE自带的Rename 为了避免混淆,用了一个命名参数,之后的所有参数都需要标明名称
    val resultD = joinToString(collection = list, separator = "(", prefix = ";", postfix = ")")

默认参数值

主要是为了解决某些类的重载函数太多,造成使用繁琐,在kotlin中可以在声明函数的时候,指定参数的默认值,这样就可以避免创建重载的函数,
//默认参数值
    fun <T> joinToStringDef(
        collection: Collection<T>,
        separator: String = "",
        prefix: String = ",",
        postfix: String = ""
    ): String {
        val result = StringBuilder(prefix)

        for ((index, element) in collection.withIndex()) {
            if (index == 0) result.append(separator)
            result.append(element)
        }
        result.append(postfix)
        return result.toString()
    }

    //使用
    val results = joinToStringDef(list)
    val resultss = joinToStringDef(list, "==")

顶层函数和顶层属性

主要是为了消除静态工具类,kollin把函数放在最上层,会被编译成这个类的静态函数,从java中调用和调用其他静态函数一样
java中调用需要增加JvmName注解

@file:JvmName("RX")
package com.example.kotlindemo.two

//默认参数值
fun <T> joinToStringDef(
    collection: Collection<T>,
    separator: String = "",
    prefix: String = ",",
    postfix: String = ""
): String {
    val result = StringBuilder(prefix)

    for ((index, element) in collection.withIndex()) {
        if (index == 0) result.append(separator)
        result.append(element)
    }
    result.append(postfix)
    return result.toString()
}

顶层属性,也是通过访问器暴露给外部使用,不常用,但是也有价值,例如计算函数的执行次数

3.3 给别人的类添加方法,扩展函数和属性

如果扩展函数在顶层文件中定义,它的作用域是整个文件,且它可以在同一个包中的任何地方访问。如果扩展函数被 public 修饰符修饰,它可以在整个项目中访问;如果被 internal 修饰符修饰,它只能在同一个模块中访问;如果被 private 修饰符修饰,它只能在声明它的文件中访问。

fun String.lastChar(): Char = this[this.length - 1]

// 文件:Extensions.kt
package com.example.myapp

// public 扩展函数,可以在整个项目中访问
fun String.customExtensionFunction(): String {
    return "Custom Extension: $this"
}

// internal 扩展函数,只能在同一个模块中访问
internal fun Int.internalExtensionFunction(): Int {
    return this * 2
}

// private 扩展函数,只能在这个文件中访问
private fun Double.privateExtensionFunction(): Double {
    return this / 2
}

扩展属性

//扩展属性
val String.lastChar: Char get() = get(length - 1)

var StringBuilder.lastChar: Char get() = get(length-1)
    set(value) {this.setCharAt(length-1,value)}

3.4 可变参数 中缀调用 解构声明

在 Kotlin 中,vararg 是一个关键字,用于表示可变数量的参数(vararg parameters)。当你使用 vararg 关键字时,你可以将任意数量的参数传递给一个函数,类似于 Java 中的可变参数(varargs)。

vararg 的使用场景
函数参数:当一个函数需要接受可变数量的参数时,可以使用 vararg。这使得调用函数时可以传递任意数量的参数,而不需要使用数组。
基本用法
定义一个可变参数函数:

fun printAll(vararg strings: String) {
    for (str in strings) {
        println(str)
    }
}

fun main() {
    printAll("Kotlin", "Java", "C++")
    // 输出:
    // Kotlin
    // Java
    // C++
}
//在上面的示例中,printAll 函数接受一个可变数量的字符串参数,使用 vararg 关键字来声明。

//传递可变参数
//将数组作为可变参数传递:

//如果你有一个数组,并希望将它作为可变参数传递给函数,可以使用展开操作符 *。

fun main() {
    val languages = arrayOf("Kotlin", "Java", "C++")
    printAll(*languages)
    // 输出:
    // Kotlin
    // Java
    // C++
}
//在上面的示例中,*languages 将数组 languages 展开为可变参数。

//与其他参数混合使用
//你可以将 vararg 参数与其他参数混合使用,但 vararg 参数必须是函数的最后一个参数,或者最后一个参数之后只能有一个以 vararg 关键字修饰的参数。

fun printMessagesWithPrefix(prefix: String, vararg messages: String) {
    for (message in messages) {
        println("$prefix $message")
    }
}

fun main() {
    printMessagesWithPrefix("Info:", "Kotlin", "Java", "C++")
    // 输出:
    // Info: Kotlin
    // Info: Java
    // Info: C++
}
//在上面的示例中,prefix 是普通参数,messages 是可变参数。

//使用泛型的 vararg
//你还可以使用泛型与 vararg 结合,定义接受可变数量的泛型参数的函数。

fun <T> printAll(vararg items: T) {
    for (item in items) {
        println(item)
    }
}

fun main() {
    printAll("Kotlin", 42, true)
    // 输出:
    // Kotlin
    // 42
    // true
}

在上面的示例中,printAll 函数接受可变数量的泛型参数 T。

总结
vararg 关键字用于声明可变数量的参数,使得函数可以接受任意数量的参数。在使用 vararg 时,可以将数组展开为可变参数,将 vararg 参数与其他参数混合使用,并与泛型结合来处理各种类型的参数。

这段代码定义了一个 Kotlin 中的扩展函数 to,这个函数使用了 infix 关键字,使其能够以中缀表示法调用。具体的解析如下:

中缀调用

infix fun Any.to(other: Any) = Pair(this, other)
1. infix 关键字
  • infix 关键字表示这个函数可以以中缀表示法调用,即不需要点号和括号,可以直接在两个对象之间调用。例如,a to b 而不是 a.to(b)
2. 扩展函数
  • fun Any.to(other: Any):定义了一个扩展函数 to,这个函数扩展了 Any 类型。由于 Any 是 Kotlin 中的顶级类型,这个扩展函数可以被所有类型的实例调用。
3. 参数和返回值
  • 函数接受一个参数 other,类型为 Any,表示任意类型。
  • 函数返回一个 Pair 对象,这个 Pair 包含了 thisotherthis 代表调用该扩展函数的对象,other 是传入的参数。

使用示例

fun main() {
    val pair = "Kotlin" to "Java"
    println(pair) // 输出: (Kotlin, Java)
}
  • 这里 "Kotlin" to "Java" 实际上等价于调用 "Kotlin".to("Java")
  • 这个调用返回一个 Pair 对象,Pair("Kotlin", "Java")

中缀表示法的优势

  • 中缀表示法可以使代码更具可读性和表达性。
  • 特别是在 DSL(领域特定语言)或处理键值对等情景中很有用。

总结

这段代码定义了一个全局扩展函数 to,可以被任何对象调用。它接收一个参数,并返回一个包含调用者对象和参数对象的 Pair。通过 infix 关键字,使得这个函数可以以中缀表示法调用,从而增强代码的可读性和简洁性。

局部函数

class User(val email: String, val password: String) {
    fun saveUser(user: User) {
        if (user.email.isEmpty()) {
            throw IllegalStateException("can't save user'")
        }
        if (user.password.isEmpty()) {
            throw IllegalStateException("can't save user password'")
        }
    }
}

//提取重复函数
class Users(val email: String, val password: String) {
    fun saveUsers(users: Users) {
        fun validate(user: User, value: String, filedName: String) {
            if (value.isEmpty()) {
                throw IllegalStateException("can't save users' ${users.email} empty $filedName")
            }
        }
    }
}

//局部函数可以访问所在函数的所有参数和变量,可以去除User
class UsersS(val email: String, val password: String)

fun saveUsers(users: UsersS) {
    fun validate(value: String, filedName: String) {
        if (value.isEmpty()) {
            throw IllegalStateException("can't save users' ${users.email} empty $filedName")
        }
    }
    validate(users.email,"Name")
}

//还可以用扩展函数来优化
class UsersSS(val email: String, val password: String)
fun UsersSS.validate(){
    fun validate(value: String, filedName: String) {
        if (value.isEmpty()) {
            throw IllegalStateException("can't save users' ${users.email} empty $filedName")
        }
    }
    validate(email,"Name")
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值