我的博客

Kotlin 简介

目录
  1. 变量
    1. 常量
    2. 变量类型
      1. 整型
      2. 浮点数
      3. 字符型
      4. 布尔类型
      5. 字符串类型
    3. 类型转换
    4. null 安全
    5. 安全调用/强制调用
    6. 类型别名
  2. 表达式与运算符
    1. in 与 !in
    2. Elvis 运算
    3. 位运算
    4. 区间运算
    5. 运算符重载
  3. 流程控制
    1. for in 循环
    2. when 分支
  4. 数组集合
    1. 数组
    2. 集合
  5. 函数
    1. 单表达式函数
    2. 默认参数
  6. 尾递归函数
  7. 函数重载/变长参数
  8. 函数类型
  9. Lambda 表达式
  10. 匿名函数

Kotlin 是 JetBrains 在 2011 年推出的一个编程语言。Kotlin 程序可以编译为 Java 字节码,直接在 JVM 上执行。也可以编译为前端或者后端的 JavaScript 代码。

Kotlin 支持函数式编程和面向对象编程。

Kotlin 代码编译为字节码时会自动生成一些额外的类(因为 Java 不允许类外定义变量、函数,Kotlin 把类外的函数放入新生成的类中)

变量

强类型语言,变量必须先声明后使用,并且需要显式或隐式的指定类型

1
2
3
4
var a = "Hello world"
var b : Int
var c : Int = 25
val pi = 3.14 // 常量不可再改变

常量

常量使用 val 声明,赋值以后无法改变其值。常量分为两种:

  1. 局部范围的常量:声明时不必赋值,第一次使用之前赋值即可
  2. 类的常量属性:声明时赋值或者构造函数中赋值

变量类型

整型

Byte: 8 bit,-128 ~ 127
Short: 16 bit, -32768(2^15)~ 32767(2^15-1)
Int:32 位,-2147483648 ~ 2147483647(2^31-1,2.147483647 10 ^ 9)
Long: 64 位,-2^63 ~ 2 ^ 63 - 1(9223372036854775807, 9.2
10 ^ 18)

Long.MAX_VALUELong.MIN_VALUE 可以访问各种变量的取值范围

Kotlin 的整型都是引用类型。都继承自 Number 类型。

虽然他们是引用类型,但是却不支持空值(null)。如果要支持空值需要变量类型后面加一个 ?

1
2
var a: Int = null // 报错
var b: Int?= null // 没错

另一个区别:带 ?的整形会被映射成 Java 中对应的包装类,不带?则映射成基本类型。

1
2
3
4
5
6
var i1:Int = 200
var i2:Int = 200
var o1:Int?= 200
var o2:Int?= 200
println(i1 === i2) // true
println(o1 === o2) // false

字面值表示

为了提高可读性,kotlin 允许数值里添加下划线分割如1_000_000,字面量支持十进制、二进制、十六进制,但不支持八进制

浮点数

Float,32 bit
Double,64 bit

三个特殊浮点值:正无穷(正数除以 0.0)、负无穷(负数除以 0.0)、非数(0.0 除以 0.0 或者对负数开方)

字符型

Char,16 bit,Unicode 编码

字面值:

  1. 单引号中的单个字符(也包括 \ 转义的字符,如 '\n' 表示回车)
  2. Unicode 值,如 '\u000a' 表示回车

布尔类型

字符串类型

基本操作

1
2
3
4
5
6
7
fun main(args: Array<String>) {
var a: String = "hello"
println(a[0])
for (ch in a) {
println(ch)
}
}

字面值:

  1. 转义字符串
  2. 原始字符串,三个引号引起来,有 trimMargin 函数

字符串模板

1
2
3
4
5
6
7
8
9
fun main(args: Array<String>) {
var price = 123
var name = "Book"
var r = """
| Name is ${name}
| Price is ${price}
""".trimMargin() // 去掉 | 和之前的空格
println(r)
}

类型转换

1
2
3
4
5
fun main(args: Array<String>) {
var a = "123"
var i = a.toInt()
println(i)
}

null 安全

变量类型分为可空和不可空,可空的变量才接受空值(变量类型加 ?)

可空类型不允许不加判断而直接调用方法和属性,从而避免了空指针错误

安全调用/强制调用

先判断后调用

1
2
3
4
5
6
fun main(args: Array<String>) {
var a: String? = "hello"
if (a != null){
println(a.length)
}
}

安全调用

1
2
3
4
5
6
fun main(args: Array<String>) {
var a: String? = "hello"
println(a?.length) // 5
a = null
println(a?.length) // null
}

强制调用

1
2
3
4
5
fun main(args: Array<String>) {
var a: String? = "hello"
a = null
println(a!!.length) // Exception in thread "main" kotlin.KotlinNullPointerException
}

类型别名

typealias 类型别名 = 已有类型

表达式与运算符

所有运算符都对应函数

5 + 6 对应 5.plus(6)

a++ 对应 a.inc()

in 与 !in

Elvis 运算

1
2
var len = if (b != null) b.length else -1
var len2= b?.length ?: -1

位运算

and、or、inv(按位非)、xor、shl(左移),shr、ushr(无符号右移),只能对 Long 和 Int 使用。

区间运算

闭区间

1
2
var range = 1 .. 3
for (num in range) // 1 2 3

半开区间

1
2
val arr = arrayOf("A", "B", "C")
for (index in 0 until arr.size) // 0, 1, 2

反向区间

1
2
var range = 3 downTo 1
for (num in range) // 3 2 1

区间步长

1
for (num in 6 downTo 1 step 2) // 6 4 2

运算符重载

流程控制

for in 循环

上文提到

when 分支

取代了 switch

数组集合

数组

创建

arrayOf
arrayOfNulls
emptyArray
Array

集合

创建

setOf
mutableSetOf
hashSetOf
LinkedSetOf
sortedSetOf

函数

1
2
3
fun fun_name(argvs) [:return value tyep] {

}

单表达式函数

1
fun sum(a: Double, b: Double): Double = a + b

返回值类型 Double 也可以省略

默认参数

1
fun func(name: String = "") {}

尾递归函数

1
2
3
tailrec fun factorial (n: Int): Int {
return if (n == 1) 1 else factorial(n-1) * n
}

使用 tailrec 修饰

函数重载/变长参数

有点混乱,变长参数和函数重载可以同时再一个函数上使用,编译器尽量匹配。

函数类型

(函数形参类型列表) -> 返回值类型

这构成了一个函数类型

Lambda 表达式

1
2
3
var sum = { a: Int, b: Int ->
a + b
}

匿名函数

相比 Lambda 表达式的好处是可以指定返回值类型

评论无需登录,可以匿名,欢迎评论!