本文将伴随大家进入Kotlin语言的正式学习生涯中,希望大家不要半途而废哦!笔者将Kotlin用于Android开发中,因此将从Android开发的视角叙述相关内容,同时将与Java语言有所联系。
1. Kotlin基本类型
1.1 数字
1.1.1 整型
整型,即整数,与Java类似,有四种内置的整型类,表示的数值范围有所不同:
类型 | 位数 | 可表示的最小值 | 可表示的最大值 |
---|---|---|---|
Byte | 8 | -128 | 127 |
Short | 16 | -32768 | 32767 |
Int | 32 | -2,147,483,648 (-231) | 2,147,483,647 (231-1) |
Long | 64 | -9,223,372,036,854,775,808 (-263) | 9,223,372,036,854,775,807 (263-1) |
所有以未超出Int
最大值的整型值初始化的变量都会推断为Int
类型。如果初始值超过了其最大值,那么推断为Long
类型。 如需显式指定Long
型值,请在该值后追加l
或L
后缀。
1 | val one = 1 // Int |
1.1.2 浮点型
Kotlin提供了Float
与Double
类型。 根据IEEE 754
标准, 两种浮点类型的十进制位数(即可以存储多少位十进制数)不同:
类型 | 位数 | 可表示的最小值 | 可表示的最大值 |
---|---|---|---|
Float | 32 | 1.4E-45 (2-149) | 3.4028235E+38 (2128-1) |
Double | 64 | 4.9E-324 (2-1074) | 1.7976931348623157E+308 (21024-1) |
与Java所不同的是,Kotlin中的数字没有隐式拓宽转换
。 例如,具有Double
参数的函数只能对Double
值调用,而不能对Float
、 Int
或者其他数字值调用。
1 | fun main() { |
1.1.3 字面常量
字面常量
这个词很有意思,字面,代表浅显不深入。在Java中,字面常量指的就是普通的数字、字符、字符串,不是这里说的基本类型。比如下面一段Java代码:
1 | int a = 1024 |
上述代码中,=
右边的就是字面常量,而=
左边的是变量。同理,Kotlin中也是这样的情况,下面是所有的字面常量:
- 十进制:123
- 长整型以大写的 L 结尾:123L
- 16 进制以 0x 开头:0x0F
- 2 进制以 0b 开头:0b00001011
注意:8进制不支持
在Kotlin里有一个很方便的设定,你可以使用下划线使数字常量更易读,而这些下划线并不会编入你的软件中,如:
1 | val oneMillion = 1_000_000 |
1.2 布尔
Kotlin中的布尔值与Java中一致,我就不多赘述了。
布尔用 Boolean 类型表示,它有两个值:true 和 false。若需要可空引用布尔会被装箱。内置的布尔运算有:
1 | val boolA = true |
1.3 字符
字符在日常开发中不是特别常用,但是它是字符串的组成部分,字符串在日常开发中确实有很重要的地位。
Char(字符型) 必需是单引号 ‘ 包含起来的,比如普通字符 ‘0’,’a’。与 Java 不一样,Kotlin 中的 Char 不能直接和数字操作,如下代码在Kotlin中是不可行的:
1 | fun check(c: Char) { |
和Java一样,特殊字符可以用反斜杠转义。 支持这几个转义序列:\t、 \b、\n、\r、\'、\"、\\ 和 \$
。 编码其他字符要用 Unicode 转义序列语法:\uFF00
。
1.4 字符串
1.4.1 String类型
和 Java 一样,String 是不可变的。Kotlin提供了方括号 []
语法可以很方便的获取字符串中的某个字符,也可以通过 for
循环来遍历:
1 | val str = "String" |
Kotlin 支持三个引号 “”” 扩起来的字符串,支持多行字符串,比如:
1 | fun main(args: Array<String>) { |
可以通过 trimMargin() 方法来删除多余的空白。默认 | 用作边界前缀,但你可以选择其他字符并作为参数传入,比如 trimMargin(“>”)。
1 | fun main(args: Array<String>) { |
1.4.2 字符串模板
Kotlin中,字符串可以包含模板表达式 ,即一些小段代码,会求值并把结果合并到字符串中。 模板表达式以美元符$
开头,由一个简单的名字构成:
1 | fun main(args: Array<String>) { |
除了插入变量还可插入一行表达式,用花括号扩起来:
1 | fun main(args: Array<String>) { |
原生字符串和转义字符串内部都支持模板。 如果你需要在原生字符串中表示字面值 $ 字符(它不支持反斜杠转义),你可以用下列语法:
1 | fun main(args: Array<String>) { |
1.5 数组
和Java中的类型后加上[]
即可声明数组变量不同,Kotlin的数组用类Array
实现,并且还有一个 size
属性及 get
和 set
方法,由于使用 []
重载了 get
和 set
方法,所以我们可以通过下标很方便的获取或者设置数组对应位置的值,使用时与Java可以达到一致。
数组的创建两种方式:一种是使用函数arrayOf();另外一种是使用工厂函数。如下所示,我们分别是两种方式创建了两个数组:
1 | fun main(args: Array<String>) { |
如上所述,[] 运算符代表调用成员函数 get() 和 set()。
注意: 与 Java 不同的是,Kotlin 中数组是不型变的(invariant)。
除了类Array,还有ByteArray, ShortArray, IntArray,用来表示各个类型的数组,省去了装箱操作,因此效率更高,其用法同Array一样。
2. 基本数据类型间的关系
2.1 类型比较
实际上 Kotlin 中没有基础数据类型,只有封装的类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针。基本类型也一样,所以在比较两个类型的时候,就有比较数据大小和比较两个对象是否相同的区别了。
在Java中大家都知道有两种比较类型相等的方式:==
双等号与equals()
方法。equals()
方法可以为我们比较两个变量的数值或者说大小是否相等,==
双等号则用于比较两个变量的地址是否相同,基本数据类型这两种方式得到的结果一致。
与Java不同的是,在 Kotlin 中,三个等号 ===
表示比较对象地址,两个 ==
表示比较两个值大小。
1 | fun main(args: Array<String>) { |
2.2 类型转换
在Java中,类型装换相当方便,隐式转换和显式转换用起来不亦乐乎。而在Kotlin中,由于不同的表示方式,较小类型并不是较大类型的子类型,较小的类型不能隐式转换为较大的类型。 这意味着在不进行显式转换的情况下我们不能把 Byte 型值赋给一个 Int 变量。
1 | val b: Byte = 1 // OK, 字面值是静态检测的 |
我们可以代用其toInt()方法。
1 | val b: Byte = 1 // OK, 字面值是静态检测的 |
Kotlin为每种数据类型都提供了下面的这些方法,可以转化为其它的类型:
1 | toByte(): Byte |
有些情况下也是可以使用自动类型转化的,前提是可以根据上下文环境推断出正确的数据类型而且数学操作符会做相应的重载。例如下面是正确的:
1 | val l = 1L + 3 // Long + Int => Long |
另外Kotlin也提供了as
关键字来完成类型的显式转换,使用方式与二元运算符相同:
1 | val b: Byte = 1 // OK, 字面值是静态检测的 |