【Android】Kotlin教程(2)

文章目录

1.空安全

为了避免NullPointerException,Kotlin的做法是不让我们给非空类型变量赋null值,但是null在Kotlin中依然存在。

kotlin 复制代码
    var str1:String = "hello world"
    str1 = null


    var str2:String? = "hello world"
    str2 = null

2.let安全调用

let 是一个作用于对象的范围函数(scope function),它允许你在给定的对象上执行一段代码块,并且在这个代码块中可以访问该对象。let 函数的一个主要用途是避免空指针异常(NullPointerException),以及简化一些常见的操作。

1.避免空指针异常:

kotlin 复制代码
val name: String? = "Alice"
name?.let {
    println("Name is $it")
}

2.简化代码:

kotlin 复制代码
val nullableString: String? = "Hello, World!"
val length = nullableString?.let {
    println("Length before trimming: ${it.length}")
    it.trim().length
}

println("Final length: $length")  // 输出 "Final length: 13"

3.返回值:

kotlin 复制代码
val nullableString: String? = " Hello, World! "
val trimmedLength = nullableString?.let {
    it.trim().length
}

println(trimmedLength)  // 输出 13

4.链式调用:

kotlin 复制代码
val person = Person()
person.name?.let { name ->
    println("Person's name is $name")
} ?: run {
    println("Person's name is not set")
}

3.非空断言操作符!!

非空断言操作符 !! 用于告诉编译器你确定某个可空类型(nullable type)的变量或表达式实际上是非空的。使用这个操作符时,如果该变量或表达式的值是 null,则会抛出一个 KotlinNullPointerException。非空断言操作符通常用于那些你非常确定不会为 null 的情况,或者你希望在值为 null 时立即处理异常的情况。

kotlin 复制代码
    str2 = null
    println(str2!!.capitalize())

4.空合并操作符 ?:

空合并操作符 ?: 是一个非常有用的操作符,用于处理可能为 null 的值。它允许你提供一个默认值,当表达式的结果为 null 时,将使用这个默认值。这有助于避免空指针异常,并使代码更加简洁和安全。

kotlin 复制代码
    val name: String? = null
    val greeting = "Hello, ${name ?: "Guest"}!"
    println(greeting)  // 输出 "Hello, Guest!"

1.提供默认值:

当你需要为一个可能为 null 的变量提供一个默认值时,可以使用空合并操作符。

kotlin 复制代码
val name: String? = null
val greeting = "Hello, ${name ?: "Guest"}!"
println(greeting)  // 输出 "Hello, Guest!"

2.简化条件语句:

kotlin 复制代码
val nullableString: String? = null
val length = (nullableString?.length ?: 0)
println(length)  // 输出 0

3.链式调用:

kotlin 复制代码
data class Person(val name: String?, val address: Address?)
data class Address(val city: String?)

val person: Person? = Person("Alice", Address(null))
val city = person?.address?.city ?: "Unknown City"
println(city)  // 输出 "Unknown City"

4.执行计算或逻辑:

kotlin 复制代码
val nullableInt: Int? = null
val result = nullableInt ?: computeDefaultValue()
println(result)

fun computeDefaultValue(): Int {
    return 42
}

5.处理集合:

你可以用空合并操作符来处理可能为 null 的集合,并提供一个默认的空集合。

kotlin 复制代码
val list: List<String>? = null
val nonNullList = list ?: listOf()
println(nonNullList)  // 输出 []

5.异常

在 Kotlin 中,异常处理机制与 Java 类似,但有一些额外的特性和改进。Kotlin 使用 try, catch, finally 语句来处理异常,并且提供了一些额外的功能,如非局部返回和更简洁的语法。

kotlin 复制代码
fun main() {
    var number:Int? = null

    try {
        checkOperation(number)
        number!!.plus(1)
    }catch (e:Exception){
        println(e)
    }
}

fun checkOperation(number: Int?){
    number ?: throw UnskilledException()
}

class UnskilledException() : IllegalArgumentException("操作不当")

6.先决条件函数

先决条件函数 (precondition function)通常是指在执行某个操作之前必须满足的条件。这些条件用于确保函数在安全和正确的状态下运行。如果先决条件不满足,函数可以选择抛出异常、返回错误代码或以其他方式处理这种情况。

7.substring

字符串截取,substring函数支持IntRange类型(表示一个整数范围的类型)的参数。

8.split函数

split函数返回的是List集合数据,List集合又支持结构语法特性,它允许你在一个表达式里给多个变量赋值,解构常用来简化变量的赋值。

kotlin 复制代码
const val NAMES = "jacky,jackson,jack"

fun main() {
    val data = NAMES.split(",")

    val (origin,dest,proxy) = NAMES.split(",")
    println("$origin $dest $proxy")

    for (name in data) {
        println(name)
    }
}

9.replace

kotlin 复制代码
    val strt1 = "The people's Republic of China"
    val str2 = strt1.replace(Regex("[aeiou]")){
        when(it.value){
            "a" -> "*"
            "e" -> "*"
            "i" -> "*"
            "o" -> "*"
            "u" -> "*"
            else -> it.value
        }
    }
    println(strt1)
    println(str2)

10.字符串比较

在Kotlin中,用==检查两个字符串中的字符是否匹配,用===检查两个变量是否指向内存堆上同一对象,而在Java中==做引用比较,做结构比较时用equals方法。

kotlin 复制代码
    val str3 = "Jackon"
    val str4 = "jackon".capitalize()
    println("$str3   $str4")
    println(str3 == str4) // true
    println(str3 === str4) // false

11.安全转换函数

安全转换函数,如果数值不能正确转换,与其触发异常不如干脆返回null

kotlin 复制代码
    val number:Int = "9".toInt() // 转换为Int类型
    val number1 :Int? = "9.0".toIntOrNull() // null
    val number2 : Int = 9.87.roundToInt() // 10 四舍五入
    val number3 = "%.2f".format(9.8779000) // 9.88

12.标准库函数

1.apply
  • apply函数可以看做是一个配置函数,你可以传入一个接受者,然后调用一系列的函数来配置使用,如果提供lambda给apply函数执行,它会返回配置好的接受者。
  • apply 函数非常适合用于对象的初始化或配置,因为它允许你直接访问和修改对象的属性,而不需要显式地引用对象。
kotlin 复制代码
fun main(){
    val file1 = File("E://i have a dream_copy.txt")
    file1.setReadable(true)
    file1.setWritable(true)
    file1.setExecutable(true)
    
    val file2 = File("E://i have a dream_copy.txt").apply { 
        setReadable(true)
        setWritable(true)
        setExecutable(true)
    }
}
2.run

run 是一个作用域函数(scope function),它允许你在对象的上下文中执行一段代码块,并且可以返回该代码块的结果。run 函数非常适合用于初始化对象、配置对象或执行一系列操作并获取结果。

kotlin 复制代码
val result = objectInstance.run {
    // 在这里可以访问和修改 objectInstance 的属性
    // this 指代 objectInstance
    // 返回值是代码块的最后一个表达式的值
}
  • objectInstance 是你要操作的对象。
  • { ... } 是一个 lambda 表达式,在这个表达式中你可以直接访问和修改 objectInstance 的属性。
  • this 关键字在 lambda 表达式中指代 objectInstance。
  • run 函数返回 lambda 表达式的最后一个表达式的值。
kotlin 复制代码
fun main(){
    data class Person(var name: String, var age: Int)

    val person = Person("", 0).run {
        name = "Alice"
        age = 30
        this  // 返回当前对象
    }

    println(person)  // 输出 Person(name=Alice, age=30)
}
kotlin 复制代码
val result = "The people's Republic of China".run(::isLong)

fun isLong(name : String) = name.length > 10
3.with

with 函数是一个作用域函数(scope function),它允许你在给定对象的上下文中执行一系列操作。与 apply 和 run 不同的是,with 需要显式地传递一个接收者对象,并且它返回的是 lambda 表达式的最后一个表达式的值,而不是接收者对象本身。

kotlin 复制代码
val result = with(objectInstance) {
    // 在这里可以访问和修改 objectInstance 的属性
    // this 指代 objectInstance
    // 返回值是代码块的最后一个表达式的值
}
kotlin 复制代码
fun main(){
    data class Person(var name: String, var age: Int)

    val person = Person("Alice", 30)
    val updatedPerson = with(person) {
        name = "Bob"
        age = 25
        this  // 返回当前对象
    }

    println(updatedPerson)  // 输出 Person(name=Bob, age=25)
}
4.also

also 是一个作用域函数(scope function),它允许你在给定对象的上下文中执行一系列操作,并且最终返回该对象本身。alsoapply 类似,但主要的区别在于 also 的 lambda 表达式中使用的是 it 来引用接收者对象,而不是 this。

kotlin 复制代码
val result = value.also { it ->
    // 在这里可以使用 value
    // it 代表 value
}
kotlin 复制代码
fun main(){
    data class User(var name: String, var email: String, var age: Int)

    val user = User("", "", 0).also {
        it.name = "Alice"
        it.email = "alice@example.com"
        it.age = 30
    }

    println(user)  // 输出 User(name=Alice, email=alice@example.com, age=30)
}
5.takeIf

takeIf 是一个非常有用的标准库函数,它允许你根据给定的条件选择性地返回对象。如果条件满足,则返回该对象;如果不满足,则返回 null。这使得takeIf成为处理条件逻辑和避免空指针异常的强大工具。

kotlin 复制代码
val result = value.takeIf { condition }
  • value 是你要检查的对象。
  • { condition } 是一个 lambda 表达式,它接受 value 作为参数并返回一个布尔值。
  • 如果 condition 为 true,则 takeIf 返回 value;否则返回 null。

条件过滤

kotlin 复制代码
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5)
    val evenNumbers = numbers.filter { it.takeIf { it % 2 == 0 } != null }

    println(evenNumbers)  // 输出 [2, 4]
}

安全访问

kotlin 复制代码
val nullableString: String? = "  Hello, World!  "
val trimmedString = nullableString?.takeIf { it.isNotBlank() }?.trim()

println(trimmedString)  // 输出 "Hello, World!"
6.takeUnless

takeUnless takeIf 的反向操作。takeUnless 函数允许你根据给定的条件选择性地返回对象。如果条件不满足(即条件表达式的结果为 false),则返回该对象;如果条件满足(即条件表达式的结果为 true),则返回 null。这使得 takeUnless 成为处理否定条件逻辑和避免空指针异常的强大工具。

相关推荐
Algorithm15763 分钟前
JVM是什么,与Java的关系是什么,以及JVM怎么实现的跨平台性
java·开发语言·jvm
Gnevergiveup4 分钟前
2024网鼎杯青龙组Web+Misc部分WP
开发语言·前端·python
边疆.18 分钟前
C++类和对象 (中)
c语言·开发语言·c++·算法
yy_xzz20 分钟前
QT编译报错:-1: error: cannot find -lGL
开发语言·qt
你不讲 wood23 分钟前
使用 Axios 上传大文件分片上传
开发语言·前端·javascript·node.js·html·html5
林浔090631 分钟前
C语言部分输入输出(printf函数与scanf函数,getchar与putchar详解,使用Linux ubuntu)
c语言·开发语言
一颗甜苞谷1 小时前
开源一款基于 JAVA 的仓库管理系统,支持三方物流和厂内物流,包含 PDA 和 WEB 端的源码
java·开发语言·开源
CLCNboss1 小时前
Mac安装Ruby
开发语言·经验分享·笔记·macos·ruby
ai产品老杨1 小时前
深度学习模型量化原理
开发语言·人工智能·python·深度学习·安全·音视频
秋恬意1 小时前
LinkedList 源码分析
java·开发语言·面试