Kotlin 基础语法
本章介绍 Kotlin 的基础语法,包括变量定义、数据类型、运算符等内容。掌握这些基础知识是编写 Kotlin 程序的前提。
变量定义
Kotlin 使用 val 和 var 关键字来定义变量:
val:定义只读变量(相当于 Java 的final),赋值后不可修改var:定义可变变量,可以多次赋值
// val - 不可变变量(推荐优先使用)
val name = "Kotlin"
val version = 1.9
// name = "Java" // 编译错误:val 不能重新赋值
// var - 可变变量
var count = 0
count = 10 // 可以重新赋值
count += 5 // count 现在是 15
显式指定类型
Kotlin 支持类型推断,但也可以显式指定类型:
// 类型推断
val message = "Hello" // 编译器推断为 String
val number = 42 // 编译器推断为 Int
// 显式指定类型
val greeting: String = "Hello World"
val age: Int = 25
val price: Double = 19.99
val isActive: Boolean = true
延迟初始化
// lateinit - 用于 var,延迟初始化
lateinit var networkManager: NetworkManager
fun init() {
networkManager = NetworkManager()
}
// lazy - 用于 val,首次访问时初始化
val database: Database by lazy {
println("Initializing database...")
Database.connect()
}
基本数据类型
Kotlin 的基本数据类型与 Java 类似,但都是对象类型:
数字类型
// 整数类型
val byte: Byte = 127 // 8位,-128 到 127
val short: Short = 32767 // 16位,-32768 到 32767
val int: Int = 2147483647 // 32位,约 -21亿 到 21亿
val long: Long = 9223372036854775807L // 64位,需要加 L 后缀
// 浮点类型
val float: Float = 3.14F // 32位,需要加 F 后缀
val double: Double = 3.1415926535 // 64位,默认浮点类型
// 数字字面量
val oneMillion = 1_000_000 // 使用下划线增加可读性
val creditCardNumber = 1234_5678_9012_3456L
字符和字符串
// 字符
val char: Char = 'A'
val digit: Char = '9'
val unicode: Char = '\u0041' // 'A'
// 字符串
val str: String = "Hello Kotlin"
// 多行字符串
val multiline = """
这是多行字符串
可以包含"引号"和特殊字符
不需要转义
""".trimIndent()
// 字符串模板
val name = "Kotlin"
val version = 1.9
val info = "Language: $name, Version: $version"
// 表达式模板
val a = 10
val b = 20
val result = "$a + $b = ${a + b}" // "10 + 20 = 30"
多美元字符串插值(Kotlin 2.1 预览)
实验性特性
多美元字符串插值是 Kotlin 2.1 的预览特性,需要启用编译选项:
// build.gradle.kts
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xmulti-dollar-interpolation")
}
}
当字符串中需要包含大量美元符号时(如 JSON Schema、模板引擎),可以使用多美元前缀来避免频繁转义:
// 传统方式:需要转义
val jsonSchema = """
{
"${'$'}schema": "https://json-schema.org/draft/2020-12/schema",
"${'$'}id": "https://example.com/schema.json"
}
"""
// 多美元插值:$$ 表示需要两个美元符号才能触发插值
val schema = $$"""
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schema.json",
"title": "$${name}" // 这里会触发插值
}
"""
// 三美元前缀:需要 $$$ 才触发插义
val template = $$$"""
Price: $$amount // 两个美元符号,不触发插值
Total: $$$${calculateTotal()} // 三个美元符号,触发插值
"""
布尔类型
val isTrue: Boolean = true
val isFalse: Boolean = false
// 布尔运算
val andResult = isTrue && isFalse // false(与)
val orResult = isTrue || isFalse // true(或)
val notResult = !isTrue // false(非)
数组
// 创建数组
val numbers = arrayOf(1, 2, 3, 4, 5)
val strings = arrayOf("Kotlin", "Java", "Python")
// 创建特定类型数组
val intArray = intArrayOf(1, 2, 3)
val doubleArray = doubleArrayOf(1.1, 2.2, 3.3)
// 创建指定大小的数组
val sizedArray = Array(5) { i -> i * 2 } // [0, 2, 4, 6, 8]
// 数组操作
val first = numbers[0] // 访问元素
numbers[0] = 10 // 修改元素
val length = numbers.size // 数组长度
val contains = 3 in numbers // 是否包含
类型转换
Kotlin 不支持隐式类型转换,需要显式转换:
val intValue: Int = 100
// 显式转换
val longValue: Long = intValue.toLong()
val doubleValue: Double = intValue.toDouble()
val stringValue: String = intValue.toString()
// 字符串转数字
val strNumber = "123"
val number = strNumber.toInt()
val safeNumber = strNumber.toIntOrNull() // 转换失败返回 null
// 安全转换
val invalidNumber = "abc"
val result = invalidNumber.toIntOrNull() ?: 0 // 转换失败使用默认值
运算符
算术运算符
val a = 10
val b = 3
val sum = a + b // 13(加法)
val difference = a - b // 7(减法)
val product = a * b // 30(乘法)
val quotient = a / b // 3(整数除法)
val remainder = a % b // 1(取余)
// 浮点除法
val floatDiv = a.toDouble() / b // 3.333...
赋值运算符
var x = 10
x += 5 // x = x + 5,结果是 15
x -= 3 // x = x - 3,结果是 12
x *= 2 // x = x * 2,结果是 24
x /= 4 // x = x / 4,结果是 6
x %= 4 // x = x % 4,结果是 2
比较运算符
val a = 10
val b = 20
val isEqual = a == b // false(等于)
val isNotEqual = a != b // true(不等于)
val isGreater = a > b // false(大于)
val isLess = a < b // true(小于)
val isGreaterOrEqual = a >= b // false(大于等于)
val isLessOrEqual = a <= b // true(小于等于)
逻辑运算符
val condition1 = true
val condition2 = false
val andResult = condition1 && condition2 // false(与)
val orResult = condition1 || condition2 // true(或)
val notResult = !condition1 // false(非)
// 短路特性
val result = condition1 && someFunction() // condition1 为 false 时不会调用 someFunction()
位运算符
val a = 0b1100 // 12
val b = 0b1010 // 10
val and = a and b // 0b1000 = 8(按位与)
val or = a or b // 0b1110 = 14(按位或)
val xor = a xor b // 0b0110 = 6(按位异或)
val inv = a.inv() // 按位取反
val leftShift = a shl 2 // 左移 2 位
val rightShift = a shr 2 // 右移 2 位
范围运算符
// 闭区间(包含起始和结束)
val range = 1..10 // 1, 2, 3, ..., 10
// 半开区间(包含起始,不包含结束)
val halfOpen = 1 until 10 // 1, 2, 3, ..., 9
// 降序范围
val descending = 10 downTo 1
// 带步长
val withStep = 1..10 step 2 // 1, 3, 5, 7, 9
// 范围检查
val x = 5
val inRange = x in 1..10 // true
val notInRange = x !in 1..4 // true
字符串操作
val str = "Hello Kotlin"
// 字符串长度
val length = str.length // 12
// 获取字符
val firstChar = str[0] // 'H'
val lastChar = str[str.length - 1] // 'n'
// 子字符串
val substring = str.substring(0, 5) // "Hello"
val substring2 = str.substring(6) // "Kotlin"
// 字符串比较
val str1 = "Kotlin"
val str2 = "kotlin"
val isSame = str1 == str2 // false(区分大小写)
val isSameIgnoreCase = str1.equals(str2, ignoreCase = true) // true
// 字符串查找
val contains = str.contains("Kotlin") // true
val startsWith = str.startsWith("Hello") // true
val endsWith = str.endsWith("!") // false
val index = str.indexOf("Kotlin") // 6
// 字符串替换
val replaced = str.replace("Kotlin", "World") // "Hello World"
// 字符串分割
val split = "a,b,c".split(",") // ["a", "b", "c"]
// 字符串修剪
val trimmed = " hello ".trim() // "hello"
// 判空
val empty = ""
val isEmpty = empty.isEmpty() // true(长度为0)
val isBlank = " ".isBlank() // true(空或仅空白字符)
val isNotEmpty = str.isNotEmpty() // true
空安全
Kotlin 的类型系统区分可空类型和不可空类型:
// 不可空类型(默认)
var nonNull: String = "Hello"
// nonNull = null // 编译错误
// 可空类型(类型后加 ?)
var nullable: String? = "Hello"
nullable = null // 可以赋值为 null
// 安全调用操作符 ?.
val length = nullable?.length // 如果 nullable 为 null,返回 null
// Elvis 操作符 ?:(提供默认值)
val len = nullable?.length ?: 0 // 如果为 null,使用 0
// 非空断言操作符 !!(慎用)
val forceLength = nullable!!.length // 如果为 null,抛出 NullPointerException
// 安全类型转换
val obj: Any = "Hello"
val str: String? = obj as? String // 如果转换失败,返回 null
注释
// 单行注释
/*
* 多行注释
* 可以跨越多行
*/
/**
* KDoc 文档注释
* 用于生成 API 文档
* @param name 参数说明
* @return 返回值说明
*/
fun greet(name: String): String {
return "Hello, $name"
}
最佳实践
1. 优先使用 val
// 推荐
val name = "Kotlin"
val items = listOf("a", "b", "c")
// 避免(除非确实需要修改)
var name = "Kotlin"
2. 使用类型推断
// 推荐
val message = "Hello"
val count = 42
// 避免(除非需要明确类型)
val message: String = "Hello"
val count: Int = 42
3. 使用字符串模板
// 推荐
val name = "Kotlin"
val message = "Hello, $name!"
// 避免
val message = "Hello, " + name + "!"
4. 安全处理可空类型
// 推荐
val length = nullable?.length ?: 0
// 避免(可能抛出异常)
val length = nullable!!.length
小结
- 变量:使用
val(不可变)和var(可变)定义变量 - 数据类型:数字、字符、字符串、布尔、数组
- 类型转换:需要显式转换,使用
toXxx()方法 - 运算符:算术、赋值、比较、逻辑、位运算、范围
- 字符串:支持模板、丰富的操作方法
- 空安全:类型系统区分可空和不可空类型
练习
- 定义不同类型的变量并打印它们的值
- 编写程序计算圆的面积和周长
- 使用字符串模板格式化输出个人信息
- 实现一个安全的类型转换函数
- 使用范围运算符遍历数字并打印