训练的目的

怎样在已有项目中快速上手kotlin

一、怎样在已有项目中配置kotlin

Kotlin培训

Kotlin培训

二、根本语法

2.1 包界说

Kotlin 中的代码能够组织成多个包。一个文件能够包括多个类或函数,每个文件也能够有自己的包界说。包界说的语法如下:
// 文件 MyFile.kt 中的包界说
package com.benben.demo.bean
 // 动态列表
class Dynamic
 // 动态详情
class DynamicDetails

2.2 类

2.2.1 界说:

2.2.1.1 办法一

class Person {
    var name: String = ""
    var age: Int = 0
    fun sayHello() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

在上面的示例中,咱们界说了一个名为 Person 的类,它有两个特点 nameage,以及一个办法 sayHello()

在 Kotlin 中,类和特点默许都是 public 可见性,办法默许是 public 可见性且 final 类型(即不能被子类重写),能够运用 open 关键字来允许子类重写。

2.2.1.2 办法二

class Person {
    var name: String = ""
    var age: Int = 0
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
    // ...
}
class Person(var name: String = "",
    var age: Int = 0 )

类的结构函数能够运用 constructor 关键字来界说,也能够直接在类名后边加上参数列表来界说。例如:

2.2.2 分类

2.2.2.1 一般类(normal class):界说类时不运用 open 关键字,不能被承继,也没有子类。是最根本的类界说方式。

class Person {
    var name: String = ""
    var age: Int = 0
    fun sayHello() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

2.2.2.2. 笼统类(abstract class):界说类时运用 abstract 关键字,不能被实例化,只能被子类承继并实现笼统办法或特点。

abstract class Person {
    var name: String = ""
    var age: Int = 0
    fun sayHello() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

2.2.2.3. 接口(interface):界说类时运用 interface 关键字,不能被实例化,只能被类实现。接口能够包括笼统办法、常量和默许实现的办法。

interface Person {
    fun sayHello()
}

2.2.2.4. 内部类(inner class):在类中界说的类,能够拜访外部类的成员变量和办法。

class Person {
    var name: String = ""
    var age: Int = 0
    fun sayHello() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

2.2.2.5. 嵌套类(nested class):在类中界说的类,不能拜访外部类的成员变量和办法。

nested class Person {
    var name: String = ""
    var age: Int = 0
    fun sayHello() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

2.2.2.6 数据类(data class):用于表明仅包括数据的类,Kotlin 自动生成 equals()、hashCode()、toString() 等办法,也能够运用 copy() 办法复制目标。

data Person {
    var name: String = ""
    var age: Int = 0
    fun sayHello() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

2.2.2.7. 枚举类(enum class):界说了一组有限的值,枚举值之间用逗号分隔。能够运用 when 表达式来匹配枚举值。

enum class Person {
    var name: String = ""
    var age: Int = 0
    fun sayHello() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

2.3 函数界说

Kotlin 中的函数能够界说在文件中,也能够界说在类中。函数界说的语法如下:

2.3.1 界说

// 界说一个函数
fun sum(a: Int, b: Int): Int {
    return a + b
}
// 调用函数
val result = sum(1, 2)

其间,functionName 表明函数名,arg1、arg2 等表明函数参数,Type1、Type2 表明参数的类型,ReturnType 表明函数回来值的类型。

2.3.2 参数

2.3.2.1 默许参数

fun add(a: Int, b: Int): Int {
    return a + b
}

在函数界说时,能够给参数指定默许值,当调用该函数时,假如省掉了该参数,则运用默许值。

2.3.2.2 可变参数

fun sum(vararg numbers: Int): Int {
    var total = 0
    for (number in numbers) {
        total += number
    }
    return total
}
println(sum(1, 2, 3, 4, 5)) // 输出:15

在函数界说时,能够运用 vararg 关键字来指定一个参数为可变参数,表明该参数能够承受恣意数量的值。例如:

2.3.2.3 高阶参数

fun add(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
    return operation(a, b)
}
val result = add(2, 3) { a, b -> a + b }
println(result) // 输出:5

在 Kotlin 中,能够将函数作为参数传递给另一个函数,或许从函数中回来另一个函数。这种函数被称为高阶函数

在这个例子中,add() 函数承受三个参数:a、b 和一个函数 operation。在调用 add() 函数时,传递了一个 lambda 表达式作为 operation 参数,表明将 a 和 b 相加。终究回来成果 5。

2.4 流程控制句子

// if 表达式
val result = if (a > b) a else b
// when 表达式
when (x) {
    1 -> print("x is 1")
    2 -> print("x is 2")
    else -> print("x is neither 1 nor 2")
}

三、空安全

Kotlin 对空指针反常进行了处理,它引入了可空类型和非空类型的概念,使得编写代码时愈加安全和可靠。

  1. 可空类型(nullable type):在类型后边加上 ? 表明该类型能够为 null
  2. 安全调用操作符(safe call operator):在目标调用办法或特点时,运用 ?. 来防止呈现 NPE。
  3. Elvis 操作符(elvis operator):运用 ?: 表明假如目标为 null,则回来默许值。
  4. 非空断语操作符(not-null assertion operator):在目标后边加上 !! 表明非空断语,即目标不为 null,否则会抛出 NPE 反常。
// 可空类型
var str: String? = null
// 安全调用操作符
val length = str?.length
// Elvis 操作符
val length2 = str?.length ?: 0
// 非空断语操作符
val length3 = str!!.length

运用空安全特功能够让代码愈加健壮和安全。但需求留意的是,过度运用 !! 非空断语操作符可能会导致代码呈现运行时反常,因而应该慎重运用。

四、扩展函数与高阶函数

4.1 扩展函数

在 Kotlin 中,扩展函数(Extension Functions)是一种非常便利的言语特性,能够为已有的类增加新的办法,而无需承继或修正该类的源代码。

扩展函数运用 fun 关键字来界说,其第一个参数为接收者类型(Receiver Type),即被扩展的类,运用 . 语法来调用。

// 为 String 类增加一个扩展函数
fun String.customFunction(): String {
    return "This is a custom function for String"
}
// 运用扩展函数
val str = "Hello World"
val result = str.customFunction()

通过扩展函数,咱们能够为规范库中的类(如 StringListInt 等)增加自界说的办法,或为咱们自己界说的类增加新的办法,然后让代码愈加简练、易读和可维护。但需求留意的是,扩展函数不能拜访被扩展类的私有或受维护的成员。

4.2 高阶函数

能够承受函数作为参数或许回来函数作为成果的函数。这种言语特性使得编写具有笼统能力的代码变得愈加容易。

// 界说一个承受函数参数的高阶函数
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y)
}
// 界说一个函数类型的变量
val add: (Int, Int) -> Int = { a, b -> a + b }
// 调用高阶函数,并传入函数类型的参数
val result = calculate(10, 5, add)

在上面的代码中,咱们界说了一个承受函数参数的高阶函数 calculate,该函数承受两个整数和一个函数类型的参数 operation,并回来 operation 的核算成果。咱们又界说了一个函数类型的变量 add,其承受两个整数并回来它们的和。最终,咱们调用 calculate 函数并传入 add 作为参数。

高阶函数在函数式编程中应用广泛,能够大大进步代码的笼统能力和可读性,使得代码愈加灵活、可重用和可维护。

4.3 常用的一些函数

4.3.1. let

函数是一种效果域函数,它能够在一个目标上履行代码块,然后回来成果。一般用于在代码块中履行一些操作,例如对目标进行非空判别、类型转化、核算等操作。let 函数的用法如下:

object?.let {
    // 在 object 不为空的情况下履行以下代码块
    // 能够运用 it 替代 object,它是履行代码块的目标
}
val str: String? = "Hello, Kotlin"
str?.let { s ->
    // s 不为 null,能够在这里对 s 进行操作
    print(s)
}

4.3.2. apply

函数是一种构建函数,它能够在一个目标上履行一系列操作,并回来该目标自身。一般用于在目标构建过程中履行一些操作,例如初始化特点、设置默许值等操作。apply 函数的用法如下:

object.apply {
    // 在 object 上履行以下代码块
    // 能够运用 this 替代 object,它是履行代码块的目标
}.run {
    // apply 函数回来 object,能够持续在其上履行其他操作
}
val person = Person().apply {
    name = "Alice"
    age = 30
    address = "123 Main St"
}

需求留意的是,letapply 函数的差异在于它们的回来值,let 函数回来履行代码块的成果,而 apply 函数回来履行代码块的目标自身。

4.3.3. run

是 Kotlin 规范库中的一种效果域函数,它能够在一个目标上履行代码块,并回来履行成果。常用于在代码块中对目标进行一些操作,例如对目标进行非空判别、类型转化、核算等操作。运用 run 函数能够使代码愈加简练、明晰、安全。

object.run {
    // 在 object 上履行以下代码块
    // 能够运用 this 替代 object,它是履行代码块的目标
    // 回来履行成果
}
val str: String? = "Hello, Kotlin"
val result = str?.run {
    // this 不为 null,能够在这里对 this 进行操作
    length
}
// result = 13

在上面的示例中,咱们运用 run 函数对一个可能为 null 的字符串进行非空判别,并在非空的情况下获取该字符串的长度,最终回来履行成果。

需求留意的是,run 函数与 let 函数类似,都能够帮助开发者编写愈加简练、明晰、安全的代码,同时也能够进步代码的可读性和可维护性。不同之处在于,run 函数能够直接运用 this 拜访目标,在代码块中能够省掉掉对目标的引用。

4.3.5. with

with 函数是 Kotlin 规范库供给的一个函数,它能够在不运用目标名的情况下,对某个目标进行一系列操作。with 函数的签名如下:

fun <T, R> with(receiver: T, block: T.() -> R): R

其间,receiver 参数表明需求进行操作的目标,block 参数是一个函数类型的参数,表明对 receiver 进行操作的代码块。block 函数类型的接收者是 T,即 receiver 目标自身。

用法如下

with(receiver) {
    // 对 receiver 进行一系列操作
}

在代码块内,能够直接运用 receiver 目标的特点和办法,而无需运用目标名进行调用。代码块履行完毕后,会回来最终一个表达式的值。

// 界说一个 Person 类
class Person(var name: String, var age: Int)
// 创建一个 Person 目标
val person = Person("Alice", 25)
// 运用 with 函数修正 Person 目标的特点
with(person) {
    name = "Bob"
    age = 30
}
// 打印修正后的特点值
println("Name: ${person.name}, Age: ${person.age}") // 输出:Name: Bob, Age: 30

在上面的代码中,咱们运用 with 函数对 person 目标进行了一系列操作,包括修正 nameage 特点的值。最终,咱们打印了修正后的特点值。

总的来说,with 函数能够简化对某个目标的多次操作,并进步代码的可读性。但需求留意的是,with 函数仅仅供给了一种简化代码的办法,并不会对代码的功能产生显著的影响。

4.3.4 其它函数

  1. also 函数:在一个目标上履行一系列操作,回来该目标自身。
  2. takeIf 函数:依据条件判别是否运用该目标,并回来成果。
  3. takeUnless 函数:依据条件判别是否不运用该目标,并回来成果。
  4. repeat 函数:重复履行代码块指定次数。

其它

  1. Kotlin 官方文档:kotlinlang.org/docs/home.h…
  2. Kotlin Playground:play.kotlinlang.org/
  3. Kotlin 专栏:www.jianshu.com/c/5b6c58d6f…
  4. Kotlin 中文网:www.kotlincn.net/
  5. Kotlin 实战:www.kotliner.cn/
  6. Kotlin 手册:www.kotlincn.net/docs/refere…
  7. Kotlin 学习笔记:www.yiibai.com/kotlin/
  8. Kotlin 知识库:www.kotlincn.net/kotlin-know…
  9. Kotlin 官方博客:blog.jetbrains.com/kotlin/
  10. Kotlin 言语教程:www.runoob.com/kotlin/kotl…