第1章:变量与常量——Kotlin的基石

各位同学,欢迎来到Kotlin的世界。

今天咱们聊点最基础的——变量与常量。别小看这章,我见过太多项目出问题,根源就是变量声明没搞明白。说白了,变量就是程序里装数据的盒子,怎么定义、怎么用,直接决定了代码的健壮性。

1.1 var与val:可变与不可变

Kotlin里声明变量有两种方式:varval。我个人的习惯是:能用 val 绝不用 var。为什么?因为不可变意味着安全。

核心区别:

  • var:可变的变量,值可以重新赋值
  • val:只读的变量,赋值后不可修改(类似Java的final)
// var 示例
var count = 10
count = 20  // 没问题

// val 示例
val name = "Kotlin"
name = "Java"  // 编译错误!Val cannot be reassigned

你想想看,如果所有变量都是可变的,多线程环境下你根本不知道谁改了它。我在项目中遇到过好几次诡异的bug,最后发现就是某个不该变的变量被意外修改了。从那以后,我写代码第一件事就是问自己:这个变量真的需要变吗?

我的建议:优先使用 val,只有确定需要改变时才用 var。这不仅是习惯,更是一种设计哲学。

1.2 基本数据类型

Kotlin的基本数据类型和Java很像,但有一些细微差别。咱们直接看表:

类型 位数 取值范围 示例
Int 32位 -2^31 ~ 2^31-1 val a: Int = 100
Long 64位 -2^63 ~ 2^63-1 val b: Long = 100L
Float 32位 约 ±3.4E38 val c: Float = 3.14F
Double 64位 约 ±1.7E308 val d: Double = 3.14
Boolean 1位 true / false val e: Boolean = true
Char 16位 Unicode字符 val f: Char = 'A'
String 可变长度 字符串 val g: String = "Hello"

嗯,这里要注意:Kotlin里没有自动类型提升。比如 Int 不能直接赋值给 Long,必须显式转换。我记得刚转Kotlin时踩过这个坑:

val intVal = 100
val longVal: Long = intVal  // 编译错误!
val longVal2: Long = intVal.toLong()  // 正确

1.3 类型推断——偷懒的艺术

Kotlin最让我舒服的特性之一就是类型推断。你不需要每次都写类型,编译器会帮你推断。说白了,就是让代码更简洁。

val message = "Hello"  // 自动推断为 String
val count = 42         // 自动推断为 Int
val pi = 3.14159       // 自动推断为 Double

但注意,类型推断不是万能的。有时候你需要明确指定类型,尤其是涉及数字运算时:

val a = 10
val b = 3
val result = a / b  // 结果是 Int 类型的 3,不是 3.333

// 想要小数结果?
val result2 = a.toDouble() / b  // 3.333...

避坑指南:我曾经在计算金额时直接用 Int 除法,结果精度丢失导致对账不平。后来我养成了习惯:涉及除法运算,先确认类型。

1.4 空安全与可空类型——Kotlin的杀手锏

空指针异常(NullPointerException)是Java程序员永远的痛。Kotlin从语言层面解决了这个问题。怎么解决的?通过可空类型和不可空类型的区分。

默认情况下,所有类型都是不可空的:

val name: String = "Kotlin"
name = null  // 编译错误!Null can not be a value of a non-null type String

如果你确实需要存储null,必须在类型后面加 ?

val nullableName: String? = null  // 没问题
val normalName: String = null     // 编译错误

那么问题来了:怎么使用可空类型?直接调用方法会报错:

val name: String? = "Kotlin"
val length = name.length  // 编译错误!Only safe (?.) or non-null asserted (!!.) calls are allowed

Kotlin提供了几种安全调用方式:

  • 安全调用运算符 ?.:如果对象为null,返回null,否则调用方法
  • Elvis运算符 ?::如果左侧为null,使用右侧默认值
  • 非空断言 !!.:强制认为非空,如果为null则抛出异常(慎用!)
val name: String? = "Kotlin"

// 安全调用
val length1 = name?.length  // 如果name为null,length1为null

// Elvis运算符
val length2 = name?.length ?: 0  // 如果name为null,length2为0

// 非空断言(不推荐)
val length3 = name!!.length  // 如果name为null,抛出NullPointerException

我的经验:项目中90%的空安全场景用 ?.?: 就能解决。!!. 我几乎不用,除非是在测试代码里。你想想看,如果每个地方都用 !!.,那Kotlin的空安全机制就白设计了。

知识体系总览

为了让你更直观地理解本章的知识结构,我画了一张图:

Kotlin变量与常量 var vs val var: 可变变量 val: 只读变量(推荐) 优先使用val 基本数据类型 Int, Long, Float Double, Boolean Char, String 注意类型转换 类型推断 编译器自动推断类型 代码更简洁 注意除法精度 空安全与可空类型 String? 可空类型 | ?. 安全调用 | ?: Elvis运算符 | !! 非空断言(慎用)

这张图把本章的核心知识点串起来了。你可以看到,变量与常量是基础,基本数据类型是工具,类型推断是语法糖,空安全是保障。四者缺一不可。

总结一下:

  • 能用 val 不用 var
  • 基本数据类型注意显式转换
  • 类型推断让代码更简洁,但别滥用
  • 空安全是Kotlin的亮点,用好 ?.?:

好了,第一章就到这里。这些概念虽然基础,但它们是Kotlin一切高级特性的根基。下一章咱们聊聊函数——怎么把代码组织得更优雅。


公众号:蓝海资料掘金营,微信deep3321