crazyandcoder

面向Android开发者kotlin教程(2-数据类型)

2021.07.08

在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数与属性。 在本篇教程种我们简单介绍 Kotlin 中使用的基本类型:数字、字符、布尔值、数组与字符串。

1 变量

Kotlin 是强类型的语言,Kotlin 要求所有的变量必须先声明、后使用,声明变量时必须显示或隐式指定变量的类型(隐式的是指,声明的时候同时初始化,这样编译的时候就可以推断出该变量的类型了,Java 新版本也加了 var 关键字)。变量可以很简单地定义成可变 var 和不可变 val 的变量。声明变量使用 var、val 关键字,如下:


var | val 变量名 [:类型] [= 初始值]

1.1 val

我们通过 val 关键字来申明一个不可变对象。这个与 Java 中使 用的 final 很相似。一个不可变对象意味着它在实例化之后就不能再去改变它的状态了。不可变对象也可以说是线程安全的,因为它们无法去改变,也不需要去定义访问控 制,因为所有线程访问到的对象都是同一个。所以在 Kotlin 中,如果我们想使用不可变性,我们编码时思考的方式需要有一些改 变。一个重要的概念是:尽可能地使用 val 。

// A String 
val s = "Example" 
s = "abc" //错误,val 申明的变量不可再赋值

// An Int
val i = 23 

1.2 var

我们通过 var 关键字申明一个可变变量,可理解为 Java 中的普通变量,用 var 关键字修饰,与 val 变量的区别是变量的值可变。

// A String 
var s = "Example" 
s = "abc" //没问题,var 申明的变量可以重新赋值


// An Int
var i = 23 

2 数字

Kotlin 整数数值三种表示方式:

  1. 十进制

  2. 二进制:以 0b 或 0B 开头的整数数值就是二进制的整数

  3. 十六进制:以 0x 或 0X 开头的整数数值就是十六进制的整数

2.1 整数

Kotlin 提供了一组表示数字的内置类型。 对于整数,有四种不同大小的类型,因此值的范围也不同。

截屏20210709 上午11.18.37.png


所有以未超出 Int 最大值的整型值初始化的变量都会推断为 Int 类型。如果初始值超过了其最大值,那么推断为 Long 类型。 如需显式指定 Long 型值,请在该值后追加 L 后缀。
// Int
val one = 1 

// Long
val threeBillion = 3000000000 

// Long
val oneLong = 1L 

// Byte
val oneByte: Byte = 1

2.2 浮点数

对于浮点数,Kotlin 提供了 Float 与 Double 类型。两种浮点类型的十进制位数(即可以存储多少位十进制数)不同。 Float 反映了 IEEE 754 单精度,而 Double 提供了双精度。


截屏20210709 上午11.18.45.png


对于以小数初始化的变量,编译器会推断为 Double 类型。 如需将一个值显式指定为 Float 类型,请添加 f 或 F 后缀。 如果这样的值包含多于 6~7 位十进制数,那么会将其舍入。

// Double
val pi = 3.14 

// Double
val e = 2.7182818284 

// Float,实际值为 2.7182817
val eFloat = 2.7182818284f 

2.3 运算

2.3.1 整数除法

跟 Java 语言一样,整数间的除法总是返回整数。会丢弃任何小数部分。

val x = 5 / 2

//true
println(x == 2) 

如需返回浮点类型,请将其中的一个参数显式转换为浮点类型。

val x = 5 / 2.toDouble()

//true
println(x == 2.5)

2.3.2 位运算

对于位运算,没有特殊字符来表示,而只可用中缀方式调用具名函数。只用于 Int 与 Long。

shl(bits) – 有符号左移
shr(bits) – 有符号右移
ushr(bits) – 无符号右移
and(bits) – 位与
or(bits) – 位或
xor(bits) – 位异或
inv() – 位非

2.4 转换

Kotlin 与 Java 不同,Kotlin 不支持取值范围小的数据类型隐式转换为取值范围大的类型。由于不同整型类型支持的数值范围存在差异,因此进行类型转换时必须注意选择合适的类型。Kotlin 为所有数值类型都提供了如下方法进行转换。

toByte():转换为 Byte 类型
toShort():转换为 Short 类型
toInt():转换为 Int 类型
toLong():转换为 Long 类型
toFloat(): 转换为 Float 类型
toDouble(): 转换为 Double 类型
toChar(): 转换为 Char 类型

Kotlin 要求不同整型的变量或值之间必须进行显式转换

3 字符

字符用 Char 类型表示。它们不能直接当作数字,字符字面值用单引号括起来: '1'。 特殊字符可以用反斜杠转义。 支持这几个转义序列:\t、 \b、\n、\r、'、"、\ 与 $。 编码其他字符要用 Unicode 转义序列语法:'\uFF00'。

fun check(c: Char) {
    // 错误:类型不兼容
    if (c == 1) { 
        // ……
    }
}

我们可以显式把字符转换为 Int 数字:

fun decimalDigitValue(c: Char): Int {
    if (c !in '0'..'9')
        throw IllegalArgumentException("Out of range")

    // 显式转换为数字
    return c.toInt() - '0'.toInt() 
}

与 Java 不同的是,Kotlin 的 Char 型变量不能当成整数值使用,Char 型变量或表达式不能赋值给整型变量,整型变量或表达式也不能赋值给 Char 型变量。简单来说,Kotlin 的 Char 型就是简简单单的字符型,不能直接当成整型使用。

4 布尔

布尔用 Boolean 类型表示,它有两个值:true 与 false。内置的布尔运算有:

  1. || – 短路逻辑或
  2. && – 短路逻辑与
  3. ! - 逻辑非

5 数组

数组在 Kotlin 中使用 Array 类来表示,另一个选项是用接受数组大小以及一个函数参数的 Array 构造函数,用作参数的函数能够返回给定索引的每个元素初始值:

// 创建一个 Array<String> 初始化为 ["0", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }

Kotlin 中数组是不型变的(invariant)。这意味着 Kotlin 不让我们把 Array 赋值给 Array,以防止可能的运行时失败。

Kotlin 也有无装箱开销的专门的类来表示原生类型数组: ByteArray、 ShortArray、IntArray 等等。这些类与 Array 并没有继承关系,但是它们有同样的方法属性集。

6 字符串

字符串用 String 类型表示。字符串是不可变的。 字符串的元素——字符可以使用索引运算符访问: s[i]。 可以用 for 循环迭代字符串:

val str= "abcdefg"

for (c in str) {
    println(c)
}

可以用 + 操作符连接字符串。这也适用于连接字符串与其他类型的值, 只要表达式中的第一个元素是字符串

val s = "abc" + 1
println(s + "def")

6.1 字符串模板

字符串字面值可以包含模板表达式 ,即一些小段代码,会求值并把结果合并到字符串中。 模板表达式以美元符($)开头,由一个简单的名字构成:

val i = 10

// 输出“i = 10”
println("i = $i") 

或者用花括号括起来的任意表达式:

val s = "abc"

// 输出“abc.length is 3”
println("$s.length is ${s.length}")