Kotlin学习第 2 课:Kotlin 基础语法:掌握变量、数据类型与运算符

在上一课中,我们搭建了 Kotlin 学习环境并完成了第一个程序。本节课将深入 Kotlin 基础语法的核心 ------ 变量、数据类型与运算符。这些是任何编程语言的基石,掌握它们将让你能够编写有实际功能的代码,为后续学习函数、类等概念打下基础。

一、变量与常量:程序中的 "数据容器"

变量和常量是存储数据的基本单元,Kotlin 对 "可变性" 有严格区分,这也是它与其他语言(如 Python)的重要区别之一。

1. var(可变变量)与 val(不可变常量)

Kotlin 中通过 varval 声明变量,核心区别在于是否可重新赋值:

  • var(variable 的缩写) :声明可变变量,可以在初始化后重新赋值;
  • val(value 的缩写) :声明不可变常量 ,初始化后不能重新赋值(类似 Java 中的 final)。
kotlin 复制代码
// 可变变量:可以重新赋值
var age = 20
age = 21  // 合法,var 允许修改

// 不可变常量:初始化后不能修改
val name = "Kotlin"
// name = "Java"  // 编译错误!val 不允许重新赋值

最佳实践 :优先使用 val,仅在确实需要修改时使用 var。这能减少代码中的 "意外修改",让程序更稳定、更易维护(尤其在多线程场景)。

2. 变量声明的两种方式:显式类型 vs 类型推导

Kotlin 是静态类型语言,但支持 "类型推导",无需每次都显式指定变量类型:

  • 显式类型指定 :格式为 var/val 变量名: 类型 = 值,明确告诉编译器变量的类型;
  • 类型推导 :格式为 var/val 变量名 = 值,编译器会根据赋值自动推断变量类型。
kotlin 复制代码
// 显式指定类型
var score: Int = 95
val pi: Double = 3.14159

// 类型推导(推荐)
var height = 175  // 编译器自动推断为 Int 类型
val isStudent = true  // 自动推断为 Boolean 类型

注意:类型推导仅在声明时赋值有效。如果声明时不赋值(延迟初始化),必须显式指定类型:

kotlin 复制代码
var address: String  // 延迟初始化,必须显式指定类型
address = "北京市朝阳区"  // 后续赋值

3. 变量作用域:变量的 "有效范围"

变量的作用域指它能被访问的代码范围,Kotlin 中主要分为局部变量全局变量

(1)局部变量

定义在函数、代码块(如 iffor 内部)中的变量,仅在所在代码块内有效:

kotlin 复制代码
fun printMessage() {
    // 函数内的局部变量,仅在 printMessage() 中可访问
    val message = "Hello, Local Variable"
    println(message)
}

fun main() {
    printMessage()
    // println(message)  // 编译错误!message 是 printMessage() 的局部变量
}

(2)全局变量

定义在类、文件顶层(不属于任何函数或类)的变量,在整个文件或类中可访问:

kotlin 复制代码
// 文件顶层的全局变量,整个文件都能访问
val globalVersion = "1.0.0"

fun checkVersion() {
    println("当前版本:$globalVersion")  // 可直接访问全局变量
}

fun main() {
    checkVersion()  // 输出:当前版本:1.0.0
}

注意:全局变量会一直占用内存,应避免过度使用。优先使用局部变量,遵循 "最小作用域原则"。


二、基本数据类型:Kotlin 的 "数据积木"

Kotlin 提供了丰富的基本数据类型,用于存储不同类型的数据。与 Java 不同,Kotlin 的基本数据类型不是 "原始类型"(如 int) ,而是 "对象类型",但仍保持高效的性能(编译时会优化为原始类型)。

1. 数值类型:存储数字的 "工具箱"

Kotlin 提供 6 种数值类型,按精度和范围从小到大排列:

Byte 8 位 -128 ~ 127 存储小整数(节省空间)
Short 16 位 -32768 ~ 32767 中等范围整数
Int 32 位 -2^31 ~ 2^31-1(约 -21 亿~21 亿) 普通整数(默认首选)
Long 64 位 -2^63 ~ 2^63-1(约 -900 亿亿~900 亿亿) 大整数
Float 32 位 单精度浮点数(约 ±3.4e38,7 位有效数字) 精度要求不高的小数
Double 64 位 双精度浮点数(约 ±1.8e308,15 位有效数字) 高精度小数(默认首选)

使用注意

  • 声明 Long 类型时,数值后需加 L 后缀:val bigNum: Long = 10000000000L
  • 声明 Float 类型时,数值后需加 F 后缀:val pi: Float = 3.14F
  • 整数默认是 Int 类型,小数默认是 Double 类型。
kotlin 复制代码
val b: Byte = 127
val s: Short = 32000
val i = 1000  // 默认为 Int
val l = 10000000000L  // Long 类型必须加 L
val f = 3.14F  // Float 类型必须加 F
val d = 3.14159  // 默认为 Double

2. 字符类型 Char:单个字符的 "容器"

Char 用于存储单个字符,用单引号 ' 包裹,与 Java 有两点关键区别

  • Kotlin 的 Char 不能直接当作数字使用(Java 中可以);
  • 支持 Unicode 字符(包括中文、表情符号等)。
kotlin 复制代码
val c1: Char = 'A'  // 英文字符
val c2: Char = '中'  // 中文字符(支持 Unicode)
val c3: Char = '\u0041'  // Unicode 编码表示(对应 'A')

// 特殊语法规则:Char 在左侧时可以与数字相加
val y1 = 'A' + 1  // 合法,结果为 'B'('A' 的 ASCII 码是 65,加 1 后为 66,对应 'B')

// 数字在左侧时不能与 Char 相加
// val y2 = 1 + 'A'  // 编译错误!Kotlin 不允许数字在左侧与 Char 直接相加

如需将 Char 转换为对应的 ASCII 码,可显式调用 toInt() 方法,这样无论顺序如何都能正确计算:

kotlin 复制代码
val charCode = 'A'.toInt()  // 转换为 ASCII 码 65
val sum = 1 + charCode  // 合法,结果为 66
println(sum.toChar())  // 输出:'B'

3. 布尔类型 Boolean:逻辑判断的 "开关"

Boolean 用于表示逻辑值,只有两个可能的值:true(真)和 false(假),主要用于条件判断(如 if 语句)。

kotlin 复制代码
val isReady = true
val hasError = false

// 逻辑判断示例
if (isReady) {
    println("准备就绪")
} else {
    println("尚未准备")
}

三、字符串类型详解:文本处理的 "利器"

字符串(String)用于存储文本,是编程中最常用的数据类型之一。Kotlin 对字符串的支持非常灵活,提供了多种便捷操作。

1. 字符串创建:单行与多行

Kotlin 支持两种字符串创建方式:

  • 单行字符串 :用双引号 "" 包裹,内容在一行内;
  • 多行字符串 :用三重引号 """ 包裹,可直接换行,保留格式(无需转义符 \n)。
kotlin 复制代码
// 单行字符串
val singleLine = "这是一个单行字符串"

// 多行字符串(保留换行和缩进)
val multiLine = """
    这是第一行
    这是第二行
    这是第三行
""".trimIndent()  // trimIndent() 用于去除每行前的多余缩进

println(multiLine)
// 输出:
// 这是第一行
// 这是第二行
// 这是第三行

注意 :多行字符串默认会保留每行开头的缩进,trimIndent() 方法可自动去除这些多余缩进,让输出更整洁。

2. 字符串拼接:连接文本的两种方式

拼接字符串有两种常用方法:

  • + 号拼接 :直接用 + 连接字符串和其他数据类型;
  • 字符串模板 :用 $ 符号引用变量或表达式,更简洁高效。
kotlin 复制代码
val name = "Kotlin"
val version = 1.9

// + 号拼接(较繁琐)
val info1 = "编程语言:" + name + ",版本:" + version
println(info1)  // 输出:编程语言:Kotlin,版本:1.9

// 字符串模板(推荐)
val info2 = "编程语言:$name,版本:$version"
println(info2)  // 输出:同上

// 模板中使用表达式(需用 ${} 包裹)
val a = 10
val b = 20
val sumStr = "两数之和:${a + b}"  // 表达式 a + b 的结果会被插入
println(sumStr)  // 输出:两数之和:30

优势 :字符串模板比 + 号拼接更高效(避免创建过多临时字符串),且代码更易读。

3. 常用字符串方法:处理文本的 "工具箱"

Kotlin 的 String 类提供了丰富的方法,以下是最常用的几个:

方法名 功能描述 示例
length 获取字符串长度(字符数) "hello".length → 5
substring(start, end) 截取子串(从 start 到 end-1) "Kotlin".substring(1, 4) → "otl"
equals(other) 判断两个字符串内容是否相等 "a".equals("A") → false
compareTo(other) 比较字符串(按字典顺序) "apple".compareTo("banana") → 负数
startsWith(prefix) 判断是否以指定前缀开头 "Kotlin".startsWith("Ko") → true
endsWith(suffix) 判断是否以指定后缀结尾 "Kotlin".endsWith("lin") → true
trim() 去除首尾空格 " hello ".trim() → "hello"
split(delimiter) 按分隔符拆分字符串为列表 "a,b,c".split(",") → ["a", "b", "c"]
kotlin 复制代码
val str = "  Kotlin Programming  "

println(str.length)  // 输出:20(包含前后空格)
println(str.trim())  // 输出:"Kotlin Programming"(去除空格)
println(str.startsWith("Ko"))  // 输出:false(原字符串前有空格)
println(str.trim().startsWith("Ko"))  // 输出:true(去除空格后)
println(str.substring(2, 8))  // 输出:"Kotlin"(截取索引 2 到 7 的字符)

四、运算符与表达式:数据运算的 "规则"

运算符用于对数据进行运算,结合变量和常量可组成表达式(有返回值的代码片段)。Kotlin 的运算符大部分与 Java 类似,但有一些细节差异。

1. 算术运算符:处理数字计算

运算符 功能 示例
+ 加法 5 + 3 → 8
- 减法 5 - 3 → 2
* 乘法 5 * 3 → 15
/ 除法 5 / 2 → 2(整数除法)
% 取余(模) 5 % 2 → 1
++ 自增 var a=1; a++ → 2
-- 自减 var b=3; b-- → 2

注意

  • 整数除法(/)会自动舍弃小数部分(如 5 / 2 = 2,而非 2.5);
  • 自增 / 自减运算符(++/--)放在变量前后的区别:
    • a++:先使用 a 的值,再自增;
    • ++a:先自增,再使用 a 的值。
kotlin 复制代码
val num1 = 10
val num2 = 3

println(num1 + num2)  // 13
println(num1 - num2)  // 7
println(num1 * num2)  // 30
println(num1 / num2)  // 3(整数除法,舍弃小数)
println(num1.toDouble() / num2)  // 3.333...(转换为 Double 后除法)
println(num1 % num2)  // 1(10 除以 3 余 1)

var count = 5
println(count++)  // 输出 5(先使用后自增)
println(count)    // 输出 6

var score = 80
println(++score)  // 输出 81(先自增后使用)
println(score)    // 输出 81

2. 赋值运算符:给变量赋值

基本赋值运算符是 =,此外还有复合赋值运算符(结合算术运算和赋值):

运算符 等价表达式 示例
= 直接赋值 a = 5
+= a = a + b a += 3 → a = a + 3
-= a = a - b a -= 2 → a = a - 2
*= a = a * b a *= 4 → a = a * 4
/= a = a / b a /= 2 → a = a / 2
%= a = a % b a %= 3 → a = a % 3
kotlin 复制代码
var x = 10

x += 5   // 等价于 x = x + 5 → x = 15
x *= 2   // 等价于 x = x * 2 → x = 30
x -= 8   // 等价于 x = x - 8 → x = 22
println(x)  // 输出:22

3. 比较运算符:判断数据关系

比较运算符用于判断两个数据的关系,返回 Boolean 类型(truefalse)。

运算符 功能描述 示例
== 比较内容是否相等(结构相等) "abc" == "abc" → true
!= 比较内容是否不相等 5 != 3 → true
> 大于 10 > 5 → true
< 小于 10 < 5 → false
>= 大于等于 5 >= 5 → true
<= 小于等于 3 <= 2 → false
=== 比较引用是否相同(引用相等) (见下方说明)

关键区别== vs ===

  • ==:检查 "结构相等"(内容是否相同),相当于 Java 的 equals() 方法;
  • ===:检查 "引用相等"(是否指向内存中的同一个对象),相当于 Java 的 == 运算符。
kotlin 复制代码
val str1 = "Hello"
val str2 = "Hello"
val str3 = String("Hello".toCharArray())  // 新建一个内容相同的字符串对象

println(str1 == str2)   // true(内容相同)
println(str1 == str3)   // true(内容相同)
println(str1 === str2)  // true(Kotlin 字符串常量池优化,引用相同)
println(str1 === str3)  // false(str3 是新对象,引用不同)

4. 逻辑运算符:组合条件判断

逻辑运算符用于连接多个布尔表达式,进行复杂逻辑判断:

运算符 功能描述 示例
&& 逻辑与(短路) true && false → false
` `
! 逻辑非 !true → false

短路特性

  • &&:如果左侧表达式为 false,则右侧表达式不会执行 (因为整体结果已确定为 false);
  • ||:如果左侧表达式为 true,则右侧表达式不会执行 (因为整体结果已确定为 true)。
kotlin 复制代码
val hasMoney = true
val hasTime = false

// 逻辑与:两个条件都为 true 才返回 true
val canBuy = hasMoney && hasTime
println(canBuy)  // false(hasTime 为 false)

// 逻辑或:至少一个条件为 true 就返回 true
val canRelax = hasMoney || hasTime
println(canRelax)  // true(hasMoney 为 true)

// 逻辑非:取反
val isPoor = !hasMoney
println(isPoor)  // false

// 短路特性示例
var count = 0
val result = false && (count++ > 0)  // 左侧为 false,右侧不执行
println(count)  // 0(count 未自增)

五、类型转换:不同数据类型的 "桥梁"

Kotlin 不支持 "隐式类型转换"(如 Java 中 int 自动转为 long),必须显式调用转换方法 。每种基本类型都提供了转换为其他类型的方法(如 toInt()toDouble() 等)。

kotlin 复制代码
val numInt: Int = 100
// val numLong: Long = numInt  // 编译错误!Kotlin 不允许隐式转换

val numLong: Long = numInt.toLong()  // 正确:显式转换为 Long
val numFloat: Float = numInt.toFloat()  // 转换为 Float
val numStr: String = numInt.toString()  // 转换为字符串

// 字符串转数字(需确保字符串内容是有效数字)
val str = "123"
val strToInt = str.toInt()  // 转换为 Int
val strToDouble = str.toDouble()  // 转换为 Double

注意 :字符串转数字时,如果内容不是有效数字(如 "abc"),会抛出 NumberFormatException 异常,后续课程会讲解如何处理这类异常。


六、实践练习:巩固基础的 "小项目"

为了帮助你巩固本节课内容,我们来编写一个简单的 "个人信息卡片" 程序,综合运用变量、数据类型和运算符:

kotlin 复制代码
fun main() {
    // 1. 定义个人信息变量
    val name = "张三"
    var age = 25
    val height: Double = 1.75
    val isStudent = true
    
    // 2. 计算明年的年龄(使用算术运算符)
    val nextYearAge = age + 1
    
    // 3. 拼接个人信息字符串(使用字符串模板)
    val info = """
        个人信息卡片
        姓名:$name
        今年年龄:$age
        明年年龄:$nextYearAge
        身高:${height}米
        是否学生:${if (isStudent) "是" else "否"}  // 模板中使用表达式
    """.trimIndent()
    
    // 4. 输出结果
    println(info)
}

尝试修改变量值或添加更多信息(如体重、爱好),观察输出变化,加深对知识点的理解。

相关推荐
阿巴斯甜11 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker11 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952712 小时前
Andorid Google 登录接入文档
android
黄林晴13 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android