当前位置: 首页 > article >正文

【Android】Kotlin教程(2)

文章目录

      • 1.空安全
      • 2.let安全调用
      • 3.非空断言操作符!!
      • 4.空合并操作符 ?:
      • 5.异常
      • 6.先决条件函数
      • 7.substring
      • 8.split函数
      • 9.replace
      • 10.字符串比较
      • 11.安全转换函数
      • 12.标准库函数
        • 1.apply
        • 2.run
        • 3.with
        • 4.also
        • 5.takeIf
        • 6.takeUnless

1.空安全

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

    var str1:String = "hello world"
    str1 = null


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

在这里插入图片描述

2.let安全调用

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

1.避免空指针异常:

val name: String? = "Alice"
name?.let {
    println("Name is $it")
}

2.简化代码:

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.返回值:

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

println(trimmedLength)  // 输出 13

4.链式调用:

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 时立即处理异常的情况。

    str2 = null
    println(str2!!.capitalize())

在这里插入图片描述

4.空合并操作符 ?:

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

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

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

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

2.简化条件语句:

val nullableString: String? = null
val length = (nullableString?.length ?: 0)
println(length)  // 输出 0

3.链式调用:

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.执行计算或逻辑:

val nullableInt: Int? = null
val result = nullableInt ?: computeDefaultValue()
println(result)

fun computeDefaultValue(): Int {
    return 42
}

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

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

5.异常

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

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集合又支持结构语法特性,它允许你在一个表达式里给多个变量赋值,解构常用来简化变量的赋值。

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

    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方法。

    val str3 = "Jackon"
    val str4 = "jackon".capitalize()
    println("$str3   $str4")
    println(str3 == str4) // true
    println(str3 === str4) // false

11.安全转换函数

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

    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 函数非常适合用于对象的初始化或配置,因为它允许你直接访问和修改对象的属性,而不需要显式地引用对象。
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 函数非常适合用于初始化对象、配置对象或执行一系列操作并获取结果。

val result = objectInstance.run {
    // 在这里可以访问和修改 objectInstance 的属性
    // this 指代 objectInstance
    // 返回值是代码块的最后一个表达式的值
}
  • objectInstance 是你要操作的对象。
  • { … } 是一个 lambda 表达式,在这个表达式中你可以直接访问和修改 objectInstance 的属性。
  • this 关键字在 lambda 表达式中指代 objectInstance。
  • run 函数返回 lambda 表达式的最后一个表达式的值。
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)
}

在这里插入图片描述


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 表达式的最后一个表达式的值,而不是接收者对象本身。

val result = with(objectInstance) {
    // 在这里可以访问和修改 objectInstance 的属性
    // this 指代 objectInstance
    // 返回值是代码块的最后一个表达式的值
}
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。

val result = value.also { it ->
    // 在这里可以使用 value
    // it 代表 value
}
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成为处理条件逻辑和避免空指针异常的强大工具。

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

条件过滤

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

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

安全访问

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 成为处理否定条件逻辑和避免空指针异常的强大工具。


http://www.kler.cn/a/370200.html

相关文章:

  • 2025年最新汽车零部件企业销售项目管理解决方案
  • ABP - 缓存模块(1)
  • 深度学习python基础(第三节) 函数、列表
  • Hnu电子电路实验2
  • 2024年博客之星主题创作|从零到一:我的技术成长与创作之路
  • HTML语言的数据库编程
  • MacOS上Homebrew 安装、配置、更改国内镜像源及使用教程
  • GEE APP:为土地分类图数据在地图上添加一个可视化图例
  • 算法备案全攻略:深度合成等五类算法的备案流程详解
  • 基于SSM土家风景文化管理系统的设计
  • 华为HarmonyOS实现实时语音识别转文本
  • 银行信贷风控专题:Python、R 语言机器学习数据挖掘应用实例合集:xgboost、决策树、随机森林、贝叶斯等
  • 论文笔记:SIBO: A Simple Booster for Parameter-Efficient Fine-Tuning
  • 合理使用动画和转场<HarmonyOS第一课>
  • 【Orange Pi 5 Linux 5.x 内核编程】-字符设备文件操作基础
  • ssm011线上旅行信息管理系统(论文+源码)_kaic
  • 基于SpringBoot的“超市进销存系统”的设计与实现(源码+数据库+文档+PPT)
  • 面向对象进阶(下)(JAVA笔记第二十五期)
  • 【STM32-HAL库】火焰传感器(STM32F407ZGT6)(附带工程下载链接)
  • spring-第十二章 GoF代理模式
  • Android Studio安装完成后,下载gradle-7.4-bin.zip出现连接超时
  • 将 Logstash 管道转换为 OpenTelemetry Collector 管道
  • JavaScript如何判断变量数据类型 - 2024最新版前端秋招面试短期突击面试题【100道】
  • SpringBoot 集成RabbitMQ 实现钉钉日报定时发送功能
  • [LeetCode] 526. 优美的排列
  • Docker | 校园网上docker pull或者docker run失败的一种解决方法