本节我们来探讨学习:Kotlin的基础类型:数字、字符、布尔和数组等。我们知道Java的类型分成两种:一种是基本类型,一种是引用类型。它们的本质区别是:
基本类型是在堆栈处分配空间存“值”,而引用类型是在堆里面分配空间存“值”。
Java的基本类型有: byte、int、short、long、float、double、char、boolean,这些类都有对应的装箱类(引用类型)。
另外,void也可以算是一种特殊的基本类型,它也有一个装箱类Void(跟我们后文讲到的Unit、Nothing相关)。因为,Void是不能new出来的,也就是不能在堆里面分配空间存对应的值。所以,Void是一开始在堆栈处分配好空间。所以,将Void归成基本类型。
在Kotlin中,一切皆是对象。所有类型都是引用类型。没有类似Java中的基本类型。但是,可以把Kotlin中对应的这几种基本数据类型,理解为Java的基本类型的装箱类。
Integer.java
public final class Integer extends Number implements Comparable<Integer> {
/**
* A constant holding the minimum value an {@code int} can
* have, -2<sup>31</sup>.
*/
@Native public static final int MIN_VALUE = 0x80000000;
/**
* A constant holding the maximum value an {@code int} can
* have, 2<sup>31</sup>-1.
*/
@Native public static final int MAX_VALUE = 0x7fffffff;
/**
* The {@code Class} instance representing the primitive type
* {@code int}.
*
* @since JDK1.1
*/
@SuppressWarnings("unchecked")
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
...
}
Kotlin中的Int类型:
public class Int private constructor() : Number(), Comparable<Int> {
companion object {
/**
* A constant holding the minimum value an instance of Int can have.
*/
public const val MIN_VALUE: Int = -2147483648
/**
* A constant holding the maximum value an instance of Int can have.
*/
public const val MAX_VALUE: Int = 2147483647
}
...
}
我们通过Java的Integer封装类,跟Kotlin的Int类的定义可以看出两者的思想上的同源性。
Kotlin的基本类型的类图结构如下图所示
![](https://img.duidaima.com/PorkBelly/Article/Big/5ecea938-39b2-44af-945c-7b45ce7f1efb.png)
4.4.1 数字(Number)类型
Kotlin 提供了如下的内置类型来表示数字(与 Java 很相近):
![](data:image/png;base64,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)
从上面的Kotlin的基本类型的类的结构图,我们可以看出这些内置的数据类型,都继承了Number和 Comparable类。例如,Byte类型的声明:
public class Byte private constructor() : Number(), Comparable<Byte> {
...
}
Kotlin 的数字类型跟 Java 基本相同。有一点不同的是,Kotlin 对于数字没有隐式拓宽转换(如 Java 中 int 可以隐式转换为long)。
注意:在 Kotlin 中字符Char不是数字。这些基本数据类型,会在运行时自动优化为Java的double、float、long、int、short、byte。
字面常量值(literal constant values)
数值常量字面值有以下几种:
十进制: 123
Long 类型用大写 L 标记: 123L
十六进制: 0x0F
二进制: 0b00001011
代码示例:
>>> 123
123
>>> 123::class
class kotlin.Int
>>> 123::class.java
int
>>> 123L
123
>>> 123L::class
class kotlin.Long
>>> 123L::class.java
long
>>> val b:Byte=128
error: the integer literal does not conform to the expected type Byte
val b:Byte=128
^
>>> val b:Byte=127
>>> b::class
class kotlin.Byte
>>> b::class.java
byte
>>> 0x0f
15
>>> 0x0F
15
>>> 0b1000
8
同样的,当我们赋值超过变量的类型的取值范围时,编译器会直接抛错。
注意: 不支持八进制
Kotlin 同样支持浮点数的常规表示方法:
默认 double:123.5、123.5e10
Float 用 f 或者 F 标记: 123.5f
代码示例:
>>> 1234.5
1234.5
>>> 1234.5::class
class kotlin.Double
>>> 1234.5::class.java
double
>>> 12.3e10
1.23E11
>>> 12.3e10::class
class kotlin.Double
>>> 456.7f
456.7
>>> 456.7f::class
class kotlin.Float
>>> 456.7f::class.java
float
我们也可以使用数字字面值中的下划线(自 1.1 起),使数字常量更易读:
>>> 1_000_000
1000000
>>> 1234_5678_9012_3456L
1234567890123456
>>> 0xFF_EC_DE_5E
4293713502
>>> 0b11010010_01101001_10010100_10010010
3530134674
在 Java 平台数字是物理存储为 JVM 的原生类型,除非我们需要一个可空的引用(如 Int?)或泛型。
后者情况下会把数字装箱。
显式转换
由于不同的表示方式,值范围较小类型并不是较大类型的子类型,是不能隐式转换的。
代码示例:
>>> val a: Int? = 1
>>> val b: Long? = a
error: type mismatch: inferred type is Int? but Long? was expected
val b: Long? = a
^
>>> val b: Byte = 1
>>> val i: Int = b
error: type mismatch: inferred type is Byte but Int was expected
val i: Int = b
^
这意味着在不进行显式转换的情况下我们不能把 Int 型值赋给一个 Long 变量。也不能把 Byte 型值赋给一个 Int 变量。
我们可以显式转换来拓宽数字
>>> val i: Int = b.toInt() // OK: 显式拓宽
每个数字类型都继承Number抽象类,其中定义了如下的转换函数:
toDouble(): Double
toFloat(): Float
toLong(): Long
toInt(): Int
toChar(): Char
toShort(): Short
toByte(): Byte
所以,在数字之间的转换,我们直接调用上面的这些转换函数即可。
运算符+重载
缺乏隐式类型转换并不显著,因为类型会从上下文推断出来,而算术运算会有重载做适当转换,例如:
val l = 1L + 3 // Long + Int => Long
这个是通过运算符+重载实现的。我们可以在Long类的源代码中看到这个plus 运算符函数的定义:
public operator fun plus(other: Byte): Long
public operator fun plus(other: Short): Long
public operator fun plus(other: Int): Long
public operator fun plus(other: Long): Long
public operator fun plus(other: Float): Float
public operator fun plus(other: Double): Double
也就是说, 编译器会把1L + 3 翻译成 1L.plus(3),然后这个传入的参数类型必须是Byte、Short、Int、Long、Float、Double中的一种。例如,我们传入一个字符Char参数,编译器就会直接抛错:
>>> 'a'
a
>>> 'a'::class
class kotlin.Char
>>> 'a'::class.java
char
>>> 1L+'a'
error: none of the following functions can be called with the arguments supplied:
public final operator fun plus(other: Byte): Long defined in kotlin.Long
public final operator fun plus(other: Double): Double defined in kotlin.Long
public final operator fun plus(other: Float): Float defined in kotlin.Long
public final operator fun plus(other: Int): Long defined in kotlin.Long
public final operator fun plus(other: Long): Long defined in kotlin.Long
public final operator fun plus(other: Short): Long defined in kotlin.Long
1L+'a'
^
运算
Kotlin支持数字运算的标准集,运算被定义为相应的类成员(但编译器会将函数调用优化为相应的指令)。对于位运算,没有特殊字符来表示,而只可用中缀方式调用命名函数(infix fun),例如:
val x = (1 shl 2) and 0x000FF000
这是完整的位运算列表(只用于 Int 和 Long):
shl(bits) – 有符号左移 (Java 的 <<)
shr(bits) – 有符号右移 (Java 的 >>)
ushr(bits) – 无符号右移 (Java 的 >>>)
and(bits) – 位与
or(bits) – 位或
xor(bits) – 位异或
inv() – 位非
4.4.2 Char: 字符(Character)类型与转义符(Escape character)
字符用 Char 类型表示。它们不能直接当作数字
fun check(c: Char) {
if (c == 1) { // 错误:类型不兼容
// ……
}
}
字符字面值用 单引号 括起来: '1'。
特殊字符可以用反斜杠转义。
Kotlin支持如下转义字符:
\t
\b
\n
\r
\`
\"
\\
\$
编码其他字符要用 Unicode 转义序列语法,例如:'\uFF00'。
Char类的函数接口定义如下:
public class Char private constructor() : Comparable<Char> {
/**
* Compares this value with the specified value for order.
* Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
* or a positive number if it's greater than other.
*/
public override fun compareTo(other: Char): Int
/** Adds the other Int value to this value resulting a Char. */
public operator fun plus(other: Int): Char
/** Subtracts the other Char value from this value resulting an Int. */
public operator fun minus(other: Char): Int
/** Subtracts the other Int value from this value resulting a Char. */
public operator fun minus(other: Int): Char
/** Increments this value. */
public operator fun inc(): Char
/** Decrements this value. */
public operator fun dec(): Char
/** Creates a range from this value to the specified [other] value. */
public operator fun rangeTo(other: Char): CharRange
/** Returns the value of this character as a `Byte`. */
public fun toByte(): Byte
/** Returns the value of this character as a `Char`. */
public fun toChar(): Char
/** Returns the value of this character as a `Short`. */
public fun toShort(): Short
/** Returns the value of this character as a `Int`. */
public fun toInt(): Int
/** Returns the value of this character as a `Long`. */
public fun toLong(): Long
/** Returns the value of this character as a `Float`. */
public fun toFloat(): Float
/** Returns the value of this character as a `Double`. */
public fun toDouble(): Double
}
我们来用代码示例这些函数的使用:
如果两个字符相等:
>>> 'a'.compareTo('a')
0
如果两个字符不相等:
>>> 'a'.compareTo('b')
-1
>>> 'a'.compareTo('c')
-1
>>> 'b'.compareTo('a')
1
>>> 'c'.compareTo('a')
1
Char字符只重载了加上Int类型的数字的+运算符:
>>> 'a'+1
b
>>> 'a'+1L
error: the integer literal does not conform to the expected type Int
'a'+1L
所以,当我们把一个Char类型值和不是Int类型的值相加,就报错了。
相减:
>>> 'a'-1
`
>>> 'c'-'a'
2
自增计算:
>>> var a='a'
>>> val b=a++
>>> a
b
>>> b
a
>>> val c=++a
>>> c
c
我们不能在字符的字面量上直接使用++:
>>> 'a'++
error: variable expected
'a'++
^
>>> ++'a'
error: variable expected
++'a'
^
范围
>>> 'a'.rangeTo('z')
a..z
>>> for(c in 'a'..'z') {print(c)}
abcdefghijklmnopqrstuvwxyz
Char的显式类型转换函数如下:
/** Returns the value of this character as a `Byte`. */
public fun toByte(): Byte
/** Returns the value of this character as a `Char`. */
public fun toChar(): Char
/** Returns the value of this character as a `Short`. */
public fun toShort(): Short
/** Returns the value of this character as a `Int`. */
public fun toInt(): Int
/** Returns the value of this character as a `Long`. */
public fun toLong(): Long
/** Returns the value of this character as a `Float`. */
public fun toFloat(): Float
/** Returns the value of this character as a `Double`. */
public fun toDouble(): Double
例如,我们显式把字符转换为 Int 数字:
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 显式转换为数字
}
测试代码:
>>> decimalDigitValue('a')
java.lang.IllegalArgumentException: Out of range
at Line24.decimalDigitValue(Unknown Source)
>>> decimalDigitValue('1')
1
4.4.3 Boolean: 布尔类型
Kotlin的布尔类型用 Boolean 类来表示,它有两个值:true 和 false。
>>> true::class
class kotlin.Boolean
>>> true::class.java
boolean
对应Java中的boolean类型。
其源码定义如下:
package kotlin
/**
* Represents a value which is either `true` or `false`. On the JVM, non-nullable values of this type are
* represented as values of the primitive type `boolean`.
*/
public class Boolean private constructor() : Comparable<Boolean> {
/**
* Returns the inverse of this boolean.
*/
public operator fun not(): Boolean
/**
* Performs a logical `and` operation between this Boolean and the [other] one.
*/
public infix fun and(other: Boolean): Boolean
/**
* Performs a logical `or` operation between this Boolean and the [other] one.
*/
public infix fun or(other: Boolean): Boolean
/**
* Performs a logical `xor` operation between this Boolean and the [other] one.
*/
public infix fun xor(other: Boolean): Boolean
public override fun compareTo(other: Boolean): Int
}
从上面我们可以看出,Boolean类的内置的布尔运算有:
! 逻辑非 not()
&& 短路逻辑与 and()
|| 短路逻辑或or()
xor 异或(相同false,不同true)
另外,Boolean还继承实现了Comparable的compareTo()函数。
代码示例:
>>> !true
false
>>> true.not()
false
>>> true && true
true
>>> true.and(false)
false
>>> true || false
true
>>> false.or(false)
false
>>> true xor true
false
>>> true xor false
true
>>> false xor false
false
>>> true > false
true
>>> true < false
false
>>> true.compareTo(false)
1
>>> true.compareTo(false)
1
>>> true.compareTo(true)
0
>>> false.compareTo(true)
-1
4.4.4 String: 字符串类型
Kotlin的字符串用 String 类型表示。对应Java中的java.lang.String。字符串是不可变的。
>>> "abc"::class
class kotlin.String
>>> "abc"::class.java
class java.lang.String
另外,在Kotlin中,String同样是final不可继承的。
代码示例:
>>> class MyString:String
error: this type is final, so it cannot be inherited from
class MyString:String
^
索引运算符 s[i]
字符串的元素——字符可以使用索引运算符 s[i]来访问。
>>> val s="abc"
>>> s
abc
>>> s[0]
a
当我们下标越界时,会抛越界错误:
>>> s[-1]
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.charAt(String.java:646)
>>> s[3]
java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.charAt(String.java:646)
从出错信息,我们可以看出,索引运算符 s[i]会被翻译成java.lang.String.charAt(), 背后调用的是Java的String类。其调用的方法是:
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
for 循环迭代字符串
我们可以用 for 循环迭代字符串:
>>> for(c in "abc") { println(c) }
a
b
c
关于字符串String类的完整的操作方法,我们可以看下源码:
public class String : Comparable<String>, CharSequence {
companion object {}
/**
* Returns a string obtained by concatenating this string with the string representation of the given [other] object.
*/
public operator fun plus(other: Any?): String
public override val length: Int
public override fun get(index: Int): Char
public override fun subSequence(startIndex: Int, endIndex: Int): CharSequence
public override fun compareTo(other: String): Int
}
类似的,字符串有一个length属性:
>>> "abc".length
3
重载+操作符
字符串类重载了+操作符,作用对象可以是任何对象,包括空引用:
>>> "abc".plus(true)
abctrue
>>> "abc"+false
abcfalse
>>> "abc"+1
abc1
>>> "abc"+1.20
abc1.2
>>> "abc"+100L
abc100
>>> "abc"+"cdef"
abccdef
>>> "abc"+null
abcnull
>>> "abc"+'z'
abcz
>>> "abc"+arrayOf(1,2,3,4,5)
abc[Ljava.lang.Integer;@3d6f0054
截取字符串的子串:
>>> "abc".subSequence(0,1)
a
>>> "abc".subSequence(0,2)
ab
>>> "abc".subSequence(0,3)
abc
>>> "abc".subSequence(0,4)
java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.substring(String.java:1951)
at java.lang.String.subSequence(String.java:1991)
字符串字面值
字符串的字面值,可以包含原生字符串可以包含换行和任意文本,也可以是带有转义字符(Escape Charactor)的转义字符串。
>>> val s = "Hello,World!\n\n\n"
>>> s
Hello,World!
>>>
转义采用传统的反斜杠方式。
原生字符串使用三个引号(""")分界符括起来,内部没有转义并且可以包含换行和任何其他字符:
>>> val text = """
... for (c in "abc")
... print(c)
... """
>>> text
for (c in "foo")
print(c)
>>>
另外,在package kotlin.text下面的Indent.kt代码中,Kotlin还定义了String类的扩展函数:
fun String.trimMargin(marginPrefix: String = "|"): String
fun String.trimIndent(): String
我们可以使用trimMargin()、trimIndent() 裁剪函数来去除前导空格。可以看出,trimMargin()函数默认使用 "|" 来作为边界字符:
>>> val text = """
... |理论是你知道是这样,但它却不好用。
... |实践是它很好用,但你不知道是为什么。
... |程序员将理论和实践结合到一起:
... |既不好用,也不知道是为什么。
... """
>>> text.trimMargin()
理论是你知道是这样,但它却不好用。
实践是它很好用,但你不知道是为什么。
程序员将理论和实践结合到一起:
既不好用,也不知道是为什么。
默认 | 用作边界前缀,但你可以选择其他字符并作为参数传入,比如 trimMargin(">")。
trimIndent()函数,则是把字符串行的左边空白对齐切割:
>>> val text="""
... Hello
... World!
... """
>>> text.trimIndent()
Hello
World!
>>> val text="""
... Hello,
... World!
... """
>>> text.trimIndent()
Hello,
World!
字符串模板
字符串可以包含模板表达式,即一些小段代码,会求值并把结果合并到字符串中。
模板表达式以美元符($)开头,由一个简单的名字构成:
>>> val h=100
>>> val str = "A hundred is $h"
>>> str
A hundred is 100
或者用花括号扩起来的任意表达式:
>>> val s = "abc"
>>> val str = "$s.length is ${s.length}"
>>> str
abc.length is 3
原生字符串和转义字符串内部都支持模板。
>>> val price=9.9
>>> val str="""Price is $$price"""
>>> str
Price is $9.9
>>> val str="Price is $$price"
>>> str
Price is $9.9
>>> val quantity=100
>>> val str="Quantity is $quantity"
>>> str
Quantity is 100
>>> val str="""Quantity is $quantity"""
>>> str
Quantity is 100
4.4.5 Array: 数组类型
数组在 Kotlin 中使用 Array 类来表示,它定义了 get 和 set 函数(映射到重载运算符 [])和 size 属性,以及一个用于变量数组的iterator()函数:
class Array<T> private constructor() {
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ……
}
我们可以使用函数 arrayOf() 来创建一个数组并传递元素值给它。这个函数签名如下:
public inline fun <reified @PureReifiable T> arrayOf(vararg elements: T): Array<T>
其中,vararg表示是一个参数个数是一个变量。
例如, arrayOf(1, 2, 3) 创建了 array [1, 2, 3] :
>>> arrayOf(1,2,3)
[Ljava.lang.Integer;@4a37191a
>>> arrayOf(1,2,3)::class
class kotlin.Array
>>> arrayOf(1,2,3)::class.java
class [Ljava.lang.Integer;
另外,Kotlin还允许不同类型元素放到一个数组中,例如:
>>> val arr = arrayOf(1,"2",true)
>>> arr
[Ljava.lang.Object;@61af1510
>>> arr.forEach{ println(it) }
1
2
true
>>> arr.forEach{ println(it::class) }
class kotlin.Int
class kotlin.String
class kotlin.Boolean
Kotlin自动把这个数组元素的类型升级为java.lang.Object, 同时,由于Kotlin拥有的类型推断的功能,我们仍然可以看到每个数组元素对应的各自的类型。
函数 arrayOfNulls() 可以用于创建一个指定大小、元素都为空的数组。这个特殊的空数组在创建的时候,我们需要指定元素的类型。如果不指定,直接按照下面这样写,会报错:
>>> arrayOfNulls(10)
error: type inference failed: Not enough information to infer parameter T in fun <reified T> arrayOfNulls(size: Int): Array<T?>
Please specify it explicitly.
arrayOfNulls(10)
^
也就是说,我们要指定
>>> arrayOfNulls<Int>(10)
[Ljava.lang.Integer;@77c10a5f
>>> arrayOfNulls<Int>(10).forEach{println(it)}
null
null
null
null
null
null
null
null
null
null
数组Array类,还提供了一个构造函数:
public inline constructor(size: Int, init: (Int) -> T)
第1个参数是数组大小,第2个参数是一个初始化函数类型的参数(关于函数类型,我们将在后面章节介绍)。
代码示例:
>>> val square = Array(10, { i -> (i*i)})
>>> square
[Ljava.lang.Integer;@6f9e08d4
>>> square.forEach{ println(it) }
0
1
4
9
16
25
36
49
64
81
如上所述,[] 运算符代表调用成员函数 get() 和 set()。
代码示例:
>>> square[3]
9
>>> square[3]=1000
>>> square.forEach{ println(it) }
0
1
4
1000
16
25
36
49
64
81
与 Java 不同的是,Kotlin 中数组不是型变的(invariant)。 Kotlin中,我们不能把 Array<String> 赋值给 Array<Any>。这地方Kotlin类型检查的限制强于Java的数组类型。
代码示例:
>>> val arrstr = arrayOf<String>("1","2","3")
>>> arrstr
[Ljava.lang.String;@39374689
>>> var arrany = arrayOf<Any>(Any(),Any(),Any())
>>> arrany
[Ljava.lang.Object;@156324b
>>> arrany = arrstr
error: type mismatch: inferred type is Array<String> but Array<Any> was expected
arrany = arrstr
^
原生数组类型
Kotlin 也有无装箱开销的专门的类来表示原生类型数组。这些原生数组类如下:
BooleanArray
ByteArray
CharArray
ShortArray
IntArray
LongArray
FloatArray
DoubleArray
BooleanArray
这些类和 Array 并没有继承关系,但它们有同样的函数和属性集。它们也都有相应的工厂方法:
/**
* Returns an array containing the specified [Double] numbers.
*/
public fun doubleArrayOf(vararg elements: Double): DoubleArray
/**
* Returns an array containing the specified [Float] numbers.
*/
public fun floatArrayOf(vararg elements: Float): FloatArray
/**
* Returns an array containing the specified [Long] numbers.
*/
public fun longArrayOf(vararg elements: Long): LongArray
/**
* Returns an array containing the specified [Int] numbers.
*/
public fun intArrayOf(vararg elements: Int): IntArray
/**
* Returns an array containing the specified characters.
*/
public fun charArrayOf(vararg elements: Char): CharArray
/**
* Returns an array containing the specified [Short] numbers.
*/
public fun shortArrayOf(vararg elements: Short): ShortArray
/**
* Returns an array containing the specified [Byte] numbers.
*/
public fun byteArrayOf(vararg elements: Byte): ByteArray
/**
* Returns an array containing the specified boolean values.
*/
public fun booleanArrayOf(vararg elements: Boolean): BooleanArray
代码示例:
>>> val x: IntArray = intArrayOf(1, 2, 3)
>>> x[0]
1