本系列内容均来自《Kotlin从小白到大牛》一书,感谢作者关东升老师。
标识符和关键字
1标识符
标识符就是变量、 常量、 函数、 属性、 类、 接口和扩展等由程序员指定的名字。 构成标识符的字符均有一定的规范, Kotlin语言中标识符的命名规则如下:
- 区分大小写: Myname与myname是两个不同的标识符。
- 首字符, 可以是下划线( _) 或字母, 但不能是数字。
- 除首字符外其他字符, 可以是下划线( _) 、 字母和数字。
- 硬关键字( Hard Keywords) 不能作为标识符, 软关键字( Soft Keywords) 、
修饰符关键字( Modifier Keywords) 在它们的适用场景之外可以作为标识符使
用。 - 特定标识符field和it。 在Kotlin语言中有两个由编译器定义的特定标识符, 它们
只能在特定场景中使用有特定的作用, 而在其他的场景中可以做标识符使用。
标识符示例如下:
public fun main(args: Array<String>) {
val `class` = "舞蹈学习班"//class是硬关键字, 前后添加反引号( `) , 可以用于声明标识符
val `π` = 3.14159 //Unicode编码, 可以用于声明标识符
var 您好 = "世界" //Unicode编码, 可以用于声明标识符
var public = "共有的" //public是修饰符关键字, 可以用于声明变量标识符
println(`class`)
println(π)
val it = 100 //it是普通标识符 ①
val ary = arrayListOf<String>("A", "B", "C") //创建一个数组
ary.forEach { println(it) } //it特定标识符 ②
}
其中class是关键字, 事实上反引号` 不是标识符的一部分, 它也可以用于其他标识
符, 如π和π
是等价的。 代码第①行和第②行都使用it标识符, 代码第①行的it标识符
是普通标识符, 是由程序员定义的, 而代码第②行的it标识符是由编译器定义的,
forEach { println(it) }中的{ println(it) }是一个Lambda表达式, it参数引
用数组中元素。
2关键字
关键字是类似于标识符的保留字符序列, 由语言本身定义好的, Kotlin语言中有70多个
关键字, 全部是小写英文字母, 以及!和?等字符构成。 分为3个大类:
- 硬关键字( Hard Keywords) , 硬关键字任何情况下都不能作为标识符, 具体包括如下关键字。
as、 as?、 break、 class、 continue、 do、 else、 false、 for、 fun、 if、
in、 !in、 interface、 is、 !is、 null、 object、 package、 return、
super、 this、 throw、 true、 try、 typealias、 val、 var、 when和while。 - 软关键字( Soft Keywords) , 软关键字是在它适用场景中不能作为标识符, 而其他场景中可以作为标识符, 具体包括如下关键字。
by、 catch、 constructor、 delegate、 dynamic、 field、 file、
finally、 get、 import、 init、 param、 property、 receiver、 set、
setparam和where。 - 修饰符关键字( Modifier Keywords) , 修饰符关键字是一种特殊的软关键字,它们用来修饰函数、 类、 接口、 参数和属性等内容, 在此场景中不能作为标识符。 而其他场景中可以作为标识符, 具体包括如下关键字。
abstract、 annotation、 companion、 const、 crossinline、 data、
enum、 external、 final、 infix、 inner、 internal、 lateinit、
noinline、 open、 operator、 out、 override、 private、 protected、
public、 reified、 sealed、 suspend、 tailrec和vararg。
常量和变量
1 变量
在Kotlin中声明变量, 就是在标识符的前面加上关键字var, 示例代码如下:
var _Hello = "HelloWorld" //声明顶层变量 ①
public fun main(args: Array<String>) {
_Hello = "Hello, World"
var scoreForStudent: Float = 0.0f ②
var y = 20 ③
y = true //编译错误 ④
}
代码第①行、 第②行和第③行分别声明了三个变量。 第①行是顶层变量。 代码第②行在声明变量的同时指定数据类型是Float。 代码第③行声明变量时, 没有指定数据类型,
Kotlin编译器会根据上下文环境自动推导出来变量的数据类型, 例如变量y由于被赋值为
20, 20默认是Int类型, 所以y变量被推导为Int类型, 所以试图给y赋值true( 布尔值)时, 会发编译错误。
2 常量和只读变量
常量和只读变量一旦初始化后就不能再被修改。 在Kotlin声明常量是在标识符的前面加上val或const val关键字, 它们的区别如下。
- val声明的是
运行期
常量, 常量是在运行时初始化
的。 - const val声明的是
编译期
常量, 常量是在编译时初始化
,只能用于顶层常量声明或声明对象中的常量声明, 而且只能是String或基本数据类型( 整数、 浮点等)
。
注:编译期常量( const val) 相当于Java中public final static所修饰的常量。 而运行期常量( val) 相当于Java中final所修饰的常量。
示例代码如下:
const val MAX_COUNT = 1000 //声明顶层常量 ①
const val _Hello1 = "Hello, world" //声明顶层常量 ②
const val _Hello2 = StringBuilder("HelloWorld")//编译错误 ③
//声明对象
object UserDAO {
const val MAX_COUNT = 100 //声明对象中的声明常量 ④
}
public fun main(args: Array<String>) {
_Hello1 = "Hello, World" //编译错误 ⑤
val scoreForStudent: Float = 0.0f ⑥
val y = 20 ⑦
y = 30 //编译错误 ⑧
const val x = 10 //编译错误 ⑨
}
代码第①行和第②行分别声明了两个顶层常量, 它们都是运行期常量。
代码第③行业试图声明StringBuilder类型的运行期顶层常量, 但是这里会发生编译错误, 因为运行期顶层常量只能是String或基本数据类型。
代码第④行是在对象中声明常量, objectUserDAO{}是对象声明。
代码第⑨行试图在函数中运行期常量, 会发生编译错误, 因为运行期常量用于顶层常量或对象中常量声明。
代码第⑤行和第⑧行会发生编译错误, 因为这里试图修改_Hello1常量值。
代码第⑥行和第⑦行是声明运行时常量。 当然, 运行期常量也可以声明为顶层的。约定 常量其实就是只读变量, 编译期常量( const val) 是更为彻底的常量, 一旦编译之后就不能再修改了。 而运行期常量( val) 还可以根据程序的运行情况初始化。 为了描述方便,将运行期常量称为“只读变量”。 默认所说的常量是编译期常量。
3 使用var还是val?
在开发过程中, 有的时选择var还是val都能满足需求, 那么选择哪一个更好呢?
原则 如果两种方式都能满足需求情况下, 原则上优先考虑使用val声明。
因为一方面val声明的变量是只读, 一旦初始化后不能修改, 这可以避免程序运行过程中错误地修改变量内容; 另一方面在声明引用类型使用val, 对象的引用不会被修改, 但是引用内容可以修改, 这样会更加安全, 也符合函数式编程的技术要求。
语句与表达式
Kotlin代码是由关键字、 标识符、 语句和表达式等内容构成, 语句和表达式是代码的重要组成部分。
1 语句
语句关注的代码执行过程
, 如for、 while和do-while等。 在Kotlin语言中, 一条语句结束后可以不加分号, 也可以加分号, 但是有一种情况必须加分号, 那就是多条语句写在一行的时候, 需要通过分号来区别语句:
var a1: Int = 10; var a2: Int = 20;
2 表达式
表达式是一般位于赋值符( =) 的右边, 并且会返回明确的结果。 下列代码中10和20是最简单形式的表达式。
var a1 = 10
val a2 = 20
在上述代码中, 直接将表达式( 10和20) 赋值给变量或常量, 并没有指定数据类型, 这因为在Kotlin编译器可以根据上下文自动推断数据类型。 上述代码也可以指定数据类型。
var a1: Int = 10
val a2: Int = 20