训练的目的
怎样在已有项目中快速上手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
的类,它有两个特点 name
和 age
,以及一个办法 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 对空指针反常进行了处理,它引入了可空类型和非空类型的概念,使得编写代码时愈加安全和可靠。
- 可空类型(nullable type):在类型后边加上
?
表明该类型能够为null
。 - 安全调用操作符(safe call operator):在目标调用办法或特点时,运用
?.
来防止呈现 NPE。 - Elvis 操作符(elvis operator):运用
?:
表明假如目标为null
,则回来默许值。 - 非空断语操作符(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()
通过扩展函数,咱们能够为规范库中的类(如 String
、List
、Int
等)增加自界说的办法,或为咱们自己界说的类增加新的办法,然后让代码愈加简练、易读和可维护。但需求留意的是,扩展函数不能拜访被扩展类的私有或受维护的成员。
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"
}
需求留意的是,let
和 apply
函数的差异在于它们的回来值,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
目标进行了一系列操作,包括修正 name
和 age
特点的值。最终,咱们打印了修正后的特点值。
总的来说,with
函数能够简化对某个目标的多次操作,并进步代码的可读性。但需求留意的是,with
函数仅仅供给了一种简化代码的办法,并不会对代码的功能产生显著的影响。
4.3.4 其它函数
-
also
函数:在一个目标上履行一系列操作,回来该目标自身。 -
takeIf
函数:依据条件判别是否运用该目标,并回来成果。 -
takeUnless
函数:依据条件判别是否不运用该目标,并回来成果。 -
repeat
函数:重复履行代码块指定次数。
其它
- Kotlin 官方文档:kotlinlang.org/docs/home.h…
- Kotlin Playground:play.kotlinlang.org/
- Kotlin 专栏:www.jianshu.com/c/5b6c58d6f…
- Kotlin 中文网:www.kotlincn.net/
- Kotlin 实战:www.kotliner.cn/
- Kotlin 手册:www.kotlincn.net/docs/refere…
- Kotlin 学习笔记:www.yiibai.com/kotlin/
- Kotlin 知识库:www.kotlincn.net/kotlin-know…
- Kotlin 官方博客:blog.jetbrains.com/kotlin/
- Kotlin 言语教程:www.runoob.com/kotlin/kotl…