most from reference
基本类型
在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还支持一个常规的浮点数符号:
双精度浮点型默认:123.5
,123.5e10
单精度浮点型由f
或F标记
:123.5f
数字文字的下划线(自1.1)
您可以使用下划线使数字常量更易读:
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'!!!
print(a == a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA == anotherBoxedA) // Prints 'true'
Kotlin系统类型分为可空类型和不可空类型,对于Kotlin的数字类型而言:
不可空类型就类似与Java中的基本数字类型,是原始的数字类型,例如:int,long,float,double等等,
可空类型就相当于引用的数字类型,例如Integer,Long,Float,Double等等。
=:赋值,在逻辑运算时也有效;
==:等于运算,比较的是值,而不是引用;
===:完全等于运算,不仅比较值,而且还比较引用,只有两者一致才为真。
显式转换
由于不同的表示,较小的类型不是较大的类型。如果他们是,我们会有以下类型的麻烦:
// 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
以下是按位操作的完整列表(仅供Int
和Long
仅供参考):
-
shl(bits)
- 已签名转移(Java's<<
) -
shr(bits)
- 签名转移权(Java's>>
) -
ushr(bits)
- 无符号转移权(Java's>>>
) -
and(bits)
- 按位和 -
or(bits)
- 按位或 -
xor(bits)
- 按位xor -
inv()
- 逐位倒置
Characters
字符由类型表示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
表示布尔值,并具有两个值:true和false。
如果需要可空引用,布尔值将被封装
内置的布尔操作包括
-
||
- 或 -
&&
- 与 -
!
- 非
数组
在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()
库函数可用于创建一个填充有空元素的给定大小的数组。
另一个选择是使用一个工厂函数,它使用数组大小和可以返回给定其索引的每个数组元素的初始值的函数:
// Creates an Array<String> with values ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })
正如我们上面所说,该[]
操作站的调用成员函数get()
和set()
。
注意:与Java不同,Kotlin中的数组是不变的。这意味着,科特林没有让我们分配Array<String>
到一个Array<Any>
,以防止可能的运行时故障(但你可以使用Array<out Any>
,请参阅类型投影)。
科特林还设有专门的类来表示基本类型数组没有拳击开销:ByteArray
, ShortArray
,IntArray
等。这些类与类没有继承关系Array
,但它们具有相同的方法和属性集。他们每个也有相应的工厂功能:
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
字符串
字符串由类型表示String
。字符串是不可变的。字符串的元素是可以通过索引操作访问的字符s[i]
。一个字符串可以重复使用for- loop:
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()
默认情况下|
用作边距前缀,但您可以选择另一个字符并作为参数传递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
"""