Kotlin基础入门

文章说明

本文内容基于Kotlin官方文档总结翻译而成,旨在为自己学习Kotlin使用。文中的代码示例、技术概念和最佳实践均参考自Kotlin官方资源和相关技术文档,如需获取最新或更详细的信息,建议查阅官方文档。


1. Kotlin语言简介

Kotlin是一种现代的、简洁而且成熟的程序设计语言,旨在使开发者更高效地编写代码。它具有以下特点:

  • 简洁性:减少样板代码,提高开发效率
  • 安全性:设计上避免了常见错误,如空指针异常
  • 互操作性:可与Java完全互操作,可以直接调用Java代码
  • 多平台:可运行在JVM、JavaScript和Native平台

Kotlin被Google官方推荐为Android开发首选语言,同时也广泛应用于后端开发、跨平台开发和数据分析等领域。

2. 开发环境设置

开始Kotlin开发前,需要安装相应的开发环境:

  1. 安装IntelliJ IDEA或Android Studio:这两个IDE都内置了Kotlin支持

  2. 创建第一个Kotlin项目

    • 在IDE中选择”新建项目”
    • 选择Kotlin语言和JVM平台
    • 完成项目创建

3. Hello World程序

以下是一个简单的Kotlin “Hello World” 程序:

fun main() {
println("Hello, world!")
}

在Kotlin中:

  • fun 关键字用于声明函数
  • main() 函数是程序的入口点
  • 函数体被花括号 {} 包围
  • println() 函数将参数输出到标准输出

4. 变量和数据类型

变量声明

Kotlin支持两种类型的变量声明:

fun main() {
// 只读变量 (一旦赋值后不能改变)
val name = "John"

// 可变变量 (可以重新赋值)
var age = 25
age = 26 // 合法操作

// name = "Jane" // 编译错误:无法为只读变量赋值
}
  • val:声明不可变变量(类似于Java中的final)
  • var:声明可变变量

推荐优先使用val,只有在确实需要变量值变化时才使用var

基本数据类型

Kotlin提供以下基本数据类型:

类别 基本类型 示例代码
整数 ByteShortIntLong val year: Int = 2025
无符号整数 UByteUShortUIntULong val score: UInt = 100u
浮点数 FloatDouble val temperature: Float = 24.5f
val price: Double = 19.99
布尔值 Boolean val isEnabled: Boolean = true
字符 Char val letter: Char = 'A'
字符串 String val message: String = "Hello"

类型推断

Kotlin具有类型推断能力,可以根据初始值自动确定变量类型:

fun main() {
val name = "John" // 推断为String类型
val age = 25 // 推断为Int类型
val height = 1.85 // 推断为Double类型

// 显式声明类型
val weight: Double = 75.5
}

字符串模板

Kotlin提供了字符串模板功能,方便在字符串中插入变量值或表达式:

fun main() {
val name = "John"
val age = 25

// 使用$引用变量
println("My name is $name")

// 使用${...}计算表达式
println("Next year I will be ${age + 1} years old")
}

输出结果:

My name is John
Next year I will be 26 years old

5. 集合类型

Kotlin提供了多种集合类型,用于存储和操作数据组:

列表 (List)

列表是有序元素集合,可以包含重复元素:

fun main() {
// 创建只读列表
val readOnlyList = listOf("Apple", "Banana", "Cherry")

// 创建可变列表
val mutableList = mutableListOf("Apple", "Banana", "Cherry")
mutableList.add("Date")

// 访问元素
println(readOnlyList[0]) // 输出: Apple
println(readOnlyList.first()) // 输出: Apple
println(readOnlyList.last()) // 输出: Cherry

// 检查元素
println("Apple" in readOnlyList) // 输出: true

// 获取列表大小
println(readOnlyList.count()) // 输出: 3
}

集合 (Set)

集合是无序元素集合,不包含重复元素:

fun main() {
// 创建只读集合
val readOnlySet = setOf("Apple", "Banana", "Cherry", "Apple")
println(readOnlySet) // 输出: [Apple, Banana, Cherry]

// 创建可变集合
val mutableSet = mutableSetOf("Apple", "Banana", "Cherry")
mutableSet.add("Date")
mutableSet.remove("Banana")
}

映射 (Map)

映射是键值对集合,每个键唯一且只映射到一个值:

fun main() {
// 创建只读映射
val readOnlyMap = mapOf(
"apple" to 100,
"banana" to 150,
"cherry" to 80
)

// 创建可变映射
val mutableMap = mutableMapOf(
"apple" to 100,
"banana" to 150,
"cherry" to 80
)

// 访问值
println(readOnlyMap["apple"]) // 输出: 100

// 修改可变映射
mutableMap["date"] = 200
mutableMap.remove("banana")

// 检查键是否存在
println("apple" in mutableMap) // 输出: true
}

6. 控制流

条件表达式

if 表达式

Kotlin中的if可以作为表达式使用,返回值:

fun main() {
val a = 5
val b = 10

// 使用if作为语句
if (a < b) {
println("a is less than b")
} else {
println("a is not less than b")
}

// 使用if作为表达式
val max = if (a > b) a else b
println("Max value is $max") // 输出: Max value is 10
}

when 表达式

when表达式是Kotlin中更强大的switch语句替代品:

fun main() {
val day = 3

// 使用when作为语句
when (day) {
1 -> println("Monday")
2 -> println("Tuesday")
3 -> println("Wednesday")
4 -> println("Thursday")
5 -> println("Friday")
6, 7 -> println("Weekend")
else -> println("Invalid day")
}

// 使用when作为表达式
val result = when (day) {
in 1..5 -> "Weekday"
6, 7 -> "Weekend"
else -> "Invalid day"
}
println(result) // 输出: Weekday
}

循环

for 循环

用于遍历集合或范围:

fun main() {
// 遍历范围
for (i in 1..5) {
println(i) // 输出: 1 2 3 4 5
}

// 遍历集合
val fruits = listOf("Apple", "Banana", "Cherry")
for (fruit in fruits) {
println(fruit)
}

// 使用indices获取索引
for (index in fruits.indices) {
println("Fruit at $index is ${fruits[index]}")
}

// 同时获取索引和值
for ((index, value) in fruits.withIndex()) {
println("Fruit at $index is $value")
}
}

while 和 do-while 循环

fun main() {
// while循环
var i = 1
while (i <= 5) {
println(i)
i++
}

// do-while循环
var j = 1
do {
println(j)
j++
} while (j <= 5)
}

7. 函数

函数声明与调用

在Kotlin中,函数使用fun关键字声明:

// 基本函数定义
fun greet(name: String): String {
return "Hello, $name!"
}

// 单行函数简化写法
fun add(a: Int, b: Int): Int = a + b

// 无返回值的函数 (返回Unit,可以省略)
fun printMessage(message: String) {
println(message)
}

fun main() {
// 调用函数
val greeting = greet("John")
println(greeting) // 输出: Hello, John!

val sum = add(5, 3)
println("5 + 3 = $sum") // 输出: 5 + 3 = 8

printMessage("This is a message")
}

默认参数和命名参数

Kotlin支持为函数参数提供默认值,并允许通过参数名进行调用:

fun createMessage(name: String, greeting: String = "Hello"): String {
return "$greeting, $name!"
}

fun main() {
// 使用所有参数
println(createMessage("John", "Hi")) // 输出: Hi, John!

// 使用默认参数
println(createMessage("John")) // 输出: Hello, John!

// 使用命名参数
println(createMessage(greeting = "Welcome", name = "John")) // 输出: Welcome, John!
}

命名参数提高了代码可读性,特别是在参数较多的函数调用中。

8. 空安全

Kotlin的类型系统旨在消除空指针异常(NullPointerException)的危险。

可空类型和非空类型

默认情况下,Kotlin中的类型是非空的:

fun main() {
// 非空类型
var name: String = "John"
// name = null // 编译错误:不能为非空类型赋null值

// 可空类型(通过在类型后添加?)
var nullableName: String? = "John"
nullableName = null // 合法操作
}

处理可空类型

Kotlin提供多种方式安全处理可空类型:

fun main() {
val nullableName: String? = null

// 1. 安全调用操作符 (?.)
println(nullableName?.length) // 输出: null

// 2. Elvis 操作符 (?:) 提供默认值
val length = nullableName?.length ?: 0
println(length) // 输出: 0

// 3. 非空断言操作符 (!!),在确定非空时使用,否则可能抛出异常
// println(nullableName!!.length) // 运行时异常: NullPointerException

// 4. 空安全的条件检查
if (nullableName != null) {
println(nullableName.length) // 智能类型转换,编译器知道这里nullableName不为空
}
}

9. 类和对象

Kotlin提供全面的面向对象编程支持。

类的定义

// 基本类定义
class Person(val name: String, var age: Int) {
// 属性
var email: String = ""

// 方法
fun printInfo() {
println("Name: $name, Age: $age, Email: $email")
}
}

fun main() {
// 创建类的实例
val person = Person("John", 25)
person.email = "john@example.com"
person.printInfo() // 输出: Name: John, Age: 25, Email: john@example.com
}

构造函数

Kotlin的类可以有一个主构造函数和多个次构造函数:

// 带主构造函数的类
class User(val name: String) {
var email: String = ""
var age: Int = 0

// 次构造函数
constructor(name: String, email: String) : this(name) {
this.email = email
}

// 另一个次构造函数
constructor(name: String, email: String, age: Int) : this(name, email) {
this.age = age
}
}

fun main() {
val user1 = User("John")
val user2 = User("Alice", "alice@example.com")
val user3 = User("Bob", "bob@example.com", 30)
}

参考资料