Skip to content

基本语法

概述

本章详细介绍Kotlin的基本语法规则,包括标识符、关键字、注释、包声明、导入语句等基础概念。掌握这些语法规则是编写正确Kotlin代码的基础。

标识符和命名规则

标识符规则

kotlin
// 有效的标识符
val name = "Kotlin"
val userName = "john_doe"
val _privateVar = 42
val `special name` = "backticks allow spaces"

// 无效的标识符(编译错误)
// val 123name = "error"     // 不能以数字开头
// val class = "error"       // 不能使用关键字
// val user-name = "error"   // 不能包含连字符

命名约定

kotlin
// 类名:PascalCase
class UserManager
class DatabaseConnection

// 函数和变量:camelCase
fun calculateTotal() {}
val firstName = "John"
var currentUser = null

// 常量:UPPER_SNAKE_CASE
const val MAX_RETRY_COUNT = 3
const val API_BASE_URL = "https://api.example.com"

// 包名:小写,用点分隔
package com.example.myapp.utils

// 文件名:PascalCase或camelCase
// UserManager.kt
// databaseUtils.kt

关键字

硬关键字(不能用作标识符)

kotlin
// 声明关键字
class MyClass
fun myFunction()
val myValue = 10
var myVariable = 20

// 控制流关键字
if (true) { }
else { }
when (x) { }
for (i in 1..10) { }
while (true) { }
do { } while (false)

// 其他关键字
import kotlin.collections.*
package com.example
return 42
throw Exception()
try { } catch (e: Exception) { }

软关键字(在特定上下文中有特殊含义)

kotlin
// 在特定位置有特殊含义
class Person {
    constructor(name: String)  // constructor是软关键字
    
    init {  // init是软关键字
        println("Initializing")
    }
    
    companion object {  // companion和object是软关键字
        const val DEFAULT_NAME = "Unknown"
    }
}

注释

单行注释

kotlin
// 这是单行注释
val name = "Kotlin"  // 行尾注释

// TODO: 实现用户验证功能
// FIXME: 修复空指针异常
// NOTE: 这个方法需要优化

多行注释

kotlin
/*
 * 这是多行注释
 * 可以跨越多行
 * 用于详细说明
 */
val version = "1.9"

/*
 * 嵌套注释也是支持的
 * /* 这是嵌套的注释 */
 * 外层注释继续
 */

文档注释 (KDoc)

kotlin
/**
 * 计算两个数的和
 * 
 * @param a 第一个数
 * @param b 第二个数
 * @return 两数之和
 * @throws IllegalArgumentException 当参数无效时
 * @since 1.0
 * @author Kotlin Developer
 */
fun add(a: Int, b: Int): Int {
    require(a >= 0 && b >= 0) { "参数必须为非负数" }
    return a + b
}

/**
 * 用户数据类
 * 
 * @property id 用户唯一标识符
 * @property name 用户姓名
 * @property email 用户邮箱地址
 * @constructor 创建一个新的用户实例
 */
data class User(
    val id: Long,
    val name: String,
    val email: String
)

包声明和导入

包声明

kotlin
// 文件开头声明包名
package com.example.myapp.models

// 包名通常反映目录结构
// src/main/kotlin/com/example/myapp/models/User.kt

导入语句

kotlin
// 导入特定类
import java.util.Date
import kotlin.math.PI

// 导入包中的所有内容
import kotlin.collections.*

// 导入并重命名(别名)
import java.util.Date as JavaDate
import kotlin.collections.List as KotlinList

// 导入顶级函数
import kotlin.math.sqrt
import kotlin.math.pow

fun main() {
    val date = JavaDate()
    val list: KotlinList<String> = listOf("a", "b", "c")
    val result = sqrt(16.0)
}

默认导入

kotlin
// 这些包会自动导入,无需显式导入
// kotlin.*
// kotlin.annotation.*
// kotlin.collections.*
// kotlin.comparisons.*
// kotlin.io.*
// kotlin.ranges.*
// kotlin.sequences.*
// kotlin.text.*

// JVM平台还会自动导入:
// java.lang.*
// kotlin.jvm.*

语句和表达式

语句 vs 表达式

kotlin
fun main() {
    // 语句:执行操作但不返回值
    println("Hello")  // 语句
    var x = 10       // 语句
    
    // 表达式:计算并返回值
    val sum = 5 + 3  // 5 + 3 是表达式
    val max = if (x > 5) x else 5  // if是表达式
    
    // when也是表达式
    val grade = when (85) {
        in 90..100 -> "A"
        in 80..89 -> "B"
        else -> "C"
    }
}

块表达式

kotlin
fun main() {
    // 块的最后一个表达式是块的值
    val result = {
        val a = 10
        val b = 20
        a + b  // 这是块的返回值
    }()
    
    println("Result: $result")  // 输出: Result: 30
    
    // 函数体也是块表达式
    fun calculate(): Int {
        val x = 5
        val y = 10
        x * y  // 返回值,等同于 return x * y
    }
}

分号

kotlin
// Kotlin中分号是可选的
val name = "Kotlin"
val version = 1.9

// 同一行多个语句需要分号分隔
val a = 1; val b = 2; val c = 3

// 通常不推荐在同一行写多个语句
// 更好的写法:
val a = 1
val b = 2
val c = 3

字面量

数字字面量

kotlin
fun main() {
    // 整数字面量
    val decimal = 123
    val long = 123L
    val hexadecimal = 0x7B
    val binary = 0b1111011
    
    // 浮点数字面量
    val double = 123.45
    val float = 123.45f
    val scientific = 1.23e2  // 123.0
    
    // 下划线分隔符(提高可读性)
    val million = 1_000_000
    val creditCard = 1234_5678_9012_3456L
    val bytes = 0xFF_EC_DE_5E
    
    println("Decimal: $decimal")
    println("Million: $million")
}

字符字面量

kotlin
fun main() {
    // 字符字面量
    val char = 'A'
    val digit = '9'
    val space = ' '
    
    // 转义字符
    val tab = '\t'
    val newline = '\n'
    val backslash = '\\'
    val quote = '\''
    val doubleQuote = '\"'
    
    // Unicode字符
    val unicode = '\u0041'  // 'A'
    val emoji = '\u1F600'   // 😀
    
    println("Char: $char")
    println("Unicode: $unicode")
}

字符串字面量

kotlin
fun main() {
    // 普通字符串
    val simple = "Hello, Kotlin!"
    
    // 转义字符串
    val escaped = "Line 1\nLine 2\tTabbed"
    
    // 原始字符串(三重引号)
    val raw = """
        |This is a raw string
        |It can contain newlines
        |And "quotes" without escaping
        |Backslashes \ are literal
    """.trimMargin()
    
    // 字符串模板
    val name = "Kotlin"
    val version = 1.9
    val template = "Welcome to $name version $version!"
    val expression = "Length of name: ${name.length}"
    
    println(template)
    println(expression)
    println(raw)
}

布尔字面量

kotlin
fun main() {
    val isTrue = true
    val isFalse = false
    
    // 布尔运算
    val and = true && false  // false
    val or = true || false   // true
    val not = !true          // false
    
    println("Boolean values: $isTrue, $isFalse")
}

操作符优先级

kotlin
fun main() {
    // 算术操作符优先级(从高到低)
    val result1 = 2 + 3 * 4      // 14 (不是 20)
    val result2 = (2 + 3) * 4    // 20
    
    // 比较操作符
    val comparison = 5 > 3 && 2 < 4  // true
    
    // 赋值操作符优先级最低
    var x = 0
    x += 2 * 3  // x = x + (2 * 3) = 6
    
    println("Results: $result1, $result2, $comparison, $x")
}

类型系统基础

基本类型

kotlin
fun main() {
    // 数字类型
    val byte: Byte = 127
    val short: Short = 32767
    val int: Int = 2147483647
    val long: Long = 9223372036854775807L
    val float: Float = 3.14f
    val double: Double = 3.14159265359
    
    // 字符类型
    val char: Char = 'K'
    
    // 布尔类型
    val boolean: Boolean = true
    
    // 字符串类型
    val string: String = "Kotlin"
    
    // 类型检查
    println("int is Int: ${int is Int}")
    println("string is String: ${string is String}")
}

可空类型

kotlin
fun main() {
    // 非空类型
    var name: String = "Kotlin"
    // name = null  // 编译错误
    
    // 可空类型
    var nullableName: String? = "Kotlin"
    nullableName = null  // 允许
    
    // 类型检查和转换
    if (nullableName != null) {
        println("Length: ${nullableName.length}")  // 智能转换
    }
    
    // 安全转换
    val obj: Any = "Hello"
    val str: String? = obj as? String  // 安全转换
    println("Safe cast result: $str")
}

作用域和可见性

局部作用域

kotlin
fun main() {
    val outerVar = "outer"
    
    if (true) {
        val innerVar = "inner"
        println("Access outer: $outerVar")  // 可以访问外部变量
        println("Access inner: $innerVar")
    }
    
    // println(innerVar)  // 编译错误:无法访问内部变量
    
    // 块作用域
    run {
        val blockVar = "block"
        println("Block variable: $blockVar")
    }
    // println(blockVar)  // 编译错误
}

函数作用域

kotlin
// 顶级函数
fun topLevelFunction() {
    println("Top level function")
}

class MyClass {
    // 成员函数
    fun memberFunction() {
        println("Member function")
    }
    
    // 局部函数
    fun outerFunction() {
        fun localFunction() {
            println("Local function")
        }
        localFunction()  // 调用局部函数
    }
}

编码约定

缩进和格式

kotlin
// 使用4个空格缩进
class Person(
    val name: String,
    val age: Int,
    val email: String
) {
    fun introduce() {
        println("Hello, I'm $name")
    }
}

// 链式调用
val result = listOf(1, 2, 3, 4, 5)
    .filter { it > 2 }
    .map { it * 2 }
    .sum()

命名约定总结

kotlin
// 包名:全小写,用点分隔
package com.example.myapp

// 类和接口:PascalCase
class UserService
interface DatabaseRepository

// 函数和属性:camelCase
fun calculateTotal() {}
val userName = "john"

// 常量:UPPER_SNAKE_CASE
const val MAX_SIZE = 100

// 枚举常量:UPPER_SNAKE_CASE
enum class Color {
    RED, GREEN, BLUE
}

常见语法错误

1. 分号使用错误

kotlin
// 错误:不必要的分号
fun main() {
    val name = "Kotlin";  // 不需要分号
    println(name);        // 不需要分号
}

// 正确
fun main() {
    val name = "Kotlin"
    println(name)
}

2. 可空性错误

kotlin
// 错误:忘记处理可空性
fun processName(name: String?) {
    // println(name.length)  // 编译错误
}

// 正确:处理可空性
fun processName(name: String?) {
    println(name?.length ?: 0)
}

3. 类型推断错误

kotlin
// 错误:模糊的类型推断
// val list = emptyList()  // 编译错误

// 正确:明确指定类型
val list = emptyList<String>()
// 或者
val list: List<String> = emptyList()

最佳实践

  1. 遵循Kotlin编码约定
  2. 使用有意义的变量和函数名
  3. 适当使用注释,特别是KDoc
  4. 保持代码简洁和可读
  5. 充分利用类型推断,但在必要时明确指定类型

下一步

掌握了基本语法后,让我们学习Kotlin的程序结构,包括类、对象、包等组织代码的方式。

下一章: 程序结构

练习题

  1. 编写一个程序,展示所有基本数据类型的使用
  2. 创建一个包含完整KDoc注释的函数
  3. 实践不同类型的字符串字面量和模板
  4. 编写代码展示操作符优先级的影响
  5. 创建一个程序来演示作用域规则

本站内容仅供学习和研究使用。