Kotlin数据类型

在Kotlin中,一切都是一个对象,可以在任何变量上调用成员函数和属性。 一些类型是内置的,因为它们的实现被优化,但是它们看起来像普通类。 在本节中,我们将介绍描述Kotlin中的大多数类型:数字,字符,布尔和数组等等。

数字类型

Kotlin以接近Java的方式来处理数字,但不完全相同。 例如,数字没有隐含的扩展转换,在某些情况下,字面量略有不同。

Kotlin提供以下代表数字的内置类型(这接近Java):

类型 位宽度
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8
注意,字符不是Kotlin中的数字。

字面常量/文字常量

对于整数值,有以下几种字面常量:
  • 整数:123
  • 长整数由大写L标记:123L
  • 十六进制:0x0F
  • 二进制:0b00001011
注意:不支持八进制字面常量。

Kotlin还支持一个常规的浮点数符号:

  • 默认为Double123.5, 123.5e10
  • 浮点数标记为fF123.5f

数字字面常量的下划线

可以使用下划线使数字常量更易读:

val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
表示

在Java平台上,数字被物理存储为JVM原始类型,除非需要一个可空的数字引用(例如Int?)或涉及泛型。 在后一种情况下,数字是装箱的。

请注意,装箱数字不一定保持身份:

val a: Int = 10000
print(a === a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA === anotherBoxedA) // !!!Prints 'false'!!!
另一方面,它保持相等:
val a: Int = 10000
print(a == a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA == anotherBoxedA) // Prints 'true'
显式转换

由于不同的表示,较小的类型不是较大的类型的子类型,就会有以下类型的麻烦:

// Hypothetical code, does not actually compile:
val a: Int? = 1 // A boxed Int (java.lang.Integer)
val b: Long? = a // implicit conversion yields a boxed Long (java.lang.Long)
print(a == b) // Surprise! This prints "false" as Long's equals() check for other part to be Long as well

因此,较小的类型不会被隐式转换为更大的类型。 这意味着不能在没有显式转换的情况下将Byte类型的值赋给Int类型的变量。

val b: Byte = 1 // OK, literals are checked statically
val i: Int = b // ERROR
可以使用显式转换来扩宽数字 - 
val i: Int = b.toInt() // OK: explicitly widened
每个数字类型都支持以下转换:
  • toByte(): Byte
  • toShort(): Short
  • toInt(): Int
  • toLong(): Long
  • toFloat(): Float
  • toDouble(): Double
  • toChar(): Char
缺少隐式转换是很少引人注意的,因为类型是从上下文推断出来的,而算术运算则被重载为适当的转换,例如 - 
val l = 1L + 3 // Long + Int => Long

操作

Kotlin支持对数字进行的算术运算的标准集合,它们被声明为适当类的成员(但编译器将调用优化为相应的指令)。请参阅操作符重载

对于按位操作,它们没有特殊的字符,但是只能命名为可以以中缀形式调用的函数,例如:

val x = (1 shl 2) and 0x000FF000

以下是按位操作的完整列表(仅适用于IntLong):

  • shl(bits) – 有符号向左移 (Java的<<)
  • shr(bits) – 有符号向右移 (Java’s >>)
  • ushr(bits) – 无符号向右移 (Java’s >>>)
  • and(bits) – 位运算符and
  • or(bits) – 位运算符or
  • xor(bits) – 位运算符xor
  • inv() – 位运算符”取反”

字符

字符由Char类型表示,它们不能直接被视为数字
fun check(c: Char) {
    if (c == 1) { // ERROR: incompatible types
        // ...
    }
}
字符文字用单引号表示:'1'。 可以使用反斜杠转义特殊字符。 支持以下转义序列:\t,\b,\n,\r,\',\",\\\$; 要编码任何其他字符,请使用Unicode转义序列语法:'\uFF00'

可以将一个字符显式转换为一个Int类型数字:

fun decimalDigitValue(c: Char): Int {
    if (c !in '0'..'9')
        throw IllegalArgumentException("Out of range")
    return c.toInt() - '0'.toInt() // Explicit conversions to numbers
}

像数字一样,当需要可空引用时,字符将被包装。标识不能被装箱操作所保留。

布尔类型

Boolean类型表示布尔值,并具有两个值:truefalse

如果需要可空引用,布尔值将可被装箱。

内置的布尔操作包括:

  • || – 懒分离
  • && – 懒结合
  • ! - 否定

数组

Kotlin中的数组由Array类表示,它有get()set()函数(通过运算符重载约定转换为[]),以及size属性以及其他一些有用的成员函数:
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(),并将数组的元素值传递给它,如:arrayOf(1,2,3)创建一个数组[1,2,3]。 或者arrayOfNulls()库函数可用于创建一个填充空(null)元素的给定大小的数组。

另一个选择是使用一个工厂函数,它使用数组大小和返回给定其索引的每个数组元素的初始值的函数:

// Creates an Array<String> with values ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })

如上所述,[]操作代表调用成员函数get()set()

注意:与Java不同,Kotlin中的数组是不变的。 这意味着Kotlin不允许将Array <String>分配给Array <Any>,这样可以防止可能的运行时故障(但可以使用Array <out Any>),详细的可参考类型投影

Kotlin还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:ByteArray, ShortArray, IntArray等等。

这些类与Array类没有继承关系,但它们具有相同的方法和属性集。它们也有相应的工厂函数:

val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]

字符串

字符串由String类型表示。字符串是不可变的。 字符串的元素可以通过索引操作的字符:s[i]来访问。可以使用for循环迭代字符串:
for (c in str) {
    println(c)
}

字符串字面量

Kotlin有两种类型的字符串字面值:可以在其中转义字符的转义字符串,以及可以包含换行符和任意文本的原始字符串。 转义的字符串非常像Java字符串:

val s = "Hello, world!\n"

使用反斜杠以常规方式完成转义。 有关支持的转义序列的列表,请参阅上述字符

原始字符串由三重引号(""")分隔,不包含转义,并且可以包含换行符和任何其他字符:

val text = """
    for (c in "foo")
        print(c)
"""
可以使用trimMargin()函数删除前导空格:
val text = """
    |Tell me and I forget.
    |Teach me and I remember.
    |Involve me and I learn.
    |(Benjamin Franklin)
    """.trimMargin()

字符串模板

字符串可以包含模板表达式,即被评估的代码片段,并且其结果被连接到字符串中。 模板表达式以美元符号($)开头以及简单名称组成:

val i = 10
val s = "i = $i" // evaluates to "i = 10"
或大括号中的任意表达式:
val s = "abc"
val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"

原始字符串和转义字符串内部都支持模板。如果您需要在原始字符串(不支持反斜杠转义)中表示一个文字$字符,则可以使用以下语法:

val price = """
${'$'}9.99
"""
联系我们

邮箱 626512443@qq.com
电话 18611320371(微信)
QQ群 235681453

Copyright © 2015-2022

备案号:京ICP备15003423号-3