Kotlin数据类型
2017-07-10 20:29
113 查看
在Kotlin中,一切都是一个对象,可以在任何变量上调用成员函数和属性。一些类型是内置的,因为它们的实现被优化,但是它们看起来像普通类。本篇博客将介绍Kotlin的四种基本类型:数字、字符、布尔型和数组。
Kotlin提供了以下六种内置的数值类型:
从上面可以看到characters在Kotlin中不属于数值类型。
Kotlin不支持八进制表示方式,支持十进制、十六进制和二进制表示
Kotlin同样支持浮点数的字面表示方式,如下:
数字字面值中可以使用下划线(Kotlin 1.1新特性)
与Java不同的是,Kotlin可以在数字字面值上使用下划线来增加可读性,如下:
先看两段代码:
和下面这段代码:
乍一看,这两段代码是一样的,但第一段代码中使用的”\=\=\=”三个”=”号,第二段代码中使用的是”\=\=”两个”\=”,下面首先介绍一下这两个运算符的区别。
- 引用相等(两个引用指向同一对象)
- 结构相等(用equals()检查)
引用相等
引用相等由\=\=\=(以及其否定形式!==)操作判断。a\=\=\=b当且仅当a和b指向同一个对象时求值为true。
结构相等
结构相等由\=\=(以及其否定形式!=)操作判断。按照惯例,像a\=\=b这样的表达式会翻译成
也就是说如果a不是null则调用equals(Any)?函数,否则(即a是null)检查b是否与null引用相等。请注意,当与null显式比较时完全没必要优化你的代码:a\=\=null会被自动转换为a\=\=\=null
介绍完相等性,再看前面两端代码就好理解了,因为
因为自动装箱创建了新对象,而两个新对象使用\=\=\=,那么就是false了。
因此,较小的类型不会被隐式转换为更大的类型。这意味着不能在没有显式转换的情况下将Byte类型的值赋给Int类型的变量。
可以使用显式转换来扩宽数字
每个数字类型都支持以下转换:
- toByte():Byte
- toShort():Short
- toInt():Int
- toLong():Long
- toFloat():Float
- toDouble(): Double
- toChar():Char
缺少隐式转换是很少引人注意的,因为类型是从上下文推断出来的,而算术运算则被重载为适当的转换,例如
对于按位操作,它们没有特殊的字符,但是只能命名为可以从中缀形式调用的函数,例如:
以下是按位操作的完整列表(仅适用于Int和Long):
- shl(bits) – 有符号向左移 (Java的<<)
- shr(bits) – 有符号向右移 (Java’s >>)
- ushr(bits) – 无符号向右移 (Java’s >>>)
- and(bits) – 位运算符and
- or(bits) – 位运算符or
- xor(bits) – 位运算符xor
- inv() – 位运算符”取反”
字符字面量以单引号括起来,比如’1’。特殊的字符可以使用转义符。下面的转移都是支持的,比如:\t,\b,\n,\r,\’,\”,\和$。 要编码任何其他字符,请使用Unicode转义序列语法:’\uFF00’。
我们可以将一个字符转成一个Int值:
像数字一样,当需要可空引用时,字符将被包装。标识不能被装箱操作所保留。
如果需要可空引用,布尔值将可被装箱。
内置的布尔操作包括:
- || – 懒分离
- && – 懒结合
- ! - 否定
要创建一个数组,我们就可以使用一个库函数arrayOf(),并将数组的元素值传递给它。如:arrayOf(1,2,3)创建一个数组[1,2,3]。或者arrayOfNulls()库函数可用于创建一个填充null元素的给定大小的数组。
另一个选择是使用一个工厂函数,它使用数组大小和返回给定其索引的每个数组元素的初始值的函数:
如上所述,[]操作代表调用成员函数get()和set()。
注意:与Java不同,Kotlin中的数组是不变的。 这意味着Kotlin不允许将Array 分配给Array ,这样可以防止可能的运行时故障(但可以使用Array ).
Kotlin还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:ByteArray, ShortArray, IntArray等等。
这些类与Array类没有继承关系,但它们具有相同的方法和属性集。它们也有相应的工厂函数:
使用反斜杠以常规方式完成转义。 有关支持的转义序列的列表,请参阅上述字符。
原始字符串由三重引号(“”“)分隔,不包含转义,并且可以包含换行符和任何其他字符:
其输出为:
可以看到,当使用”“”时,就会按照字符串的样式输出。
可以使用trimMargin()函数删除前导空格:
结果输出如下:
可以看到一个有空格并且有”|”,一个则没有。
默认使用|作边距前缀,但您可以选择另一个字符,并将其作为参数传递:trimMargin(“>”)。
Kotlin相等性
数字类型
Kotlin处理数值型类型和Java类似,但不完全一样。例如,数字没有隐含的扩展转换,在某些情况下,字面量稍有不同。Kotlin提供了以下六种内置的数值类型:
类型 | 长度(字节) |
---|---|
Double | 8 |
Float | 4 |
Long | 8 |
Int | 4 |
Short | 2 |
Byte | 1 |
字面常量
Kotlin支持以下几种形式表示整形字面量:val a = 123 val b = 123L val c = 0xff val d = 0b00110100
Kotlin不支持八进制表示方式,支持十进制、十六进制和二进制表示
Kotlin同样支持浮点数的字面表示方式,如下:
//浮点型字面常量表示 val e=2.34 //浮点型默认为double类型 val f=3.2f //如果要使用float类型,需要加入f或F
数字字面值中可以使用下划线(Kotlin 1.1新特性)
与Java不同的是,Kotlin可以在数字字面值上使用下划线来增加可读性,如下:
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'
乍一看,这两段代码是一样的,但第一段代码中使用的”\=\=\=”三个”=”号,第二段代码中使用的是”\=\=”两个”\=”,下面首先介绍一下这两个运算符的区别。
相等性
Kotlin中有两种类型的相等性:- 引用相等(两个引用指向同一对象)
- 结构相等(用equals()检查)
引用相等
引用相等由\=\=\=(以及其否定形式!==)操作判断。a\=\=\=b当且仅当a和b指向同一个对象时求值为true。
结构相等
结构相等由\=\=(以及其否定形式!=)操作判断。按照惯例,像a\=\=b这样的表达式会翻译成
a?.equals(b) ?: (b === null)
也就是说如果a不是null则调用equals(Any)?函数,否则(即a是null)检查b是否与null引用相等。请注意,当与null显式比较时完全没必要优化你的代码:a\=\=null会被自动转换为a\=\=\=null
介绍完相等性,再看前面两端代码就好理解了,因为
val boxedA: Int? = a //会自动装箱,会形成一个新对象
因为自动装箱创建了新对象,而两个新对象使用\=\=\=,那么就是false了。
显式转换
由于不同的表示,较小的类型不是较大的类型的子类型,就会有以下类型的麻烦。// 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的<<)
- 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类型表示布尔值,并具有两个值: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()库函数可用于创建一个填充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 分配给Array ,这样可以防止可能的运行时故障(但可以使用Array ).
Kotlin还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:ByteArray, ShortArray, IntArray等等。
这些类与Array类没有继承关系,但它们具有相同的方法和属性集。它们也有相应的工厂函数:
val x: IntArray = intArrayOf(1, 2, 3) x[0] = x[1] + x[2]
字符串类型
字符串由String类型表示。字符串是不可变的。字符串的元素可以通过索引操作字符:s[i]来访问。可以使用for循环迭代字符串://字符串 val s = "Hello,Kotlin" //可以使用s[i]操作字符串索引 println(s[1]) //可以使用for循环迭代字符串 for (c in s) { println(c) }
字符串字面量
Kotlin有两种类型的字符串字面值:可以在其中转义字符的转义字符串,以及可以包含换行符和任意文本的原始字符串。 转义的字符串非常像Java字符串:val s = "Hello, world!\n"
使用反斜杠以常规方式完成转义。 有关支持的转义序列的列表,请参阅上述字符。
原始字符串由三重引号(“”“)分隔,不包含转义,并且可以包含换行符和任何其他字符:
val text = """ for (c in "foo") print(c) """
其输出为:
for(c in "foo") print(c)
可以看到,当使用”“”时,就会按照字符串的样式输出。
可以使用trimMargin()函数删除前导空格:
val text1=""" |Tell me and I forget. |Teach me and I remember. |Involve me and I learn |(Benjamin Franklin) """ println(text1) println(text1.trimMargin())
结果输出如下:
|Tell me and I forget. |Teach me and I remember. |Involve me and I learn |(Benjamin Franklin) Tell me and I forget. Teach me and I remember. Involve me and I learn (Benjamin Franklin)
可以看到一个有空格并且有”|”,一个则没有。
默认使用|作边距前缀,但您可以选择另一个字符,并将其作为参数传递:trimMargin(“>”)。
字符串模板
关于字符串模板的介绍可以参考:字符串模板参考
Kotlin数据类型Kotlin相等性
相关文章推荐
- Kotlin学习之基本数据类型的学习
- Kotlin的八大基本数据类型以及if语句,三元运算符
- Kotlin 基本数据类型
- Kotlin------数据类型和语法
- Kotlin------数据类型和语法
- Step into Kotlin - 02 - 数据类型
- 《Kotlin极简教程》第三章 Kotlin基本数据类型
- Kotlin for Android(三)Kotlin数据类型
- Kotlin教程学习-数据类型
- 分享下学习Kotlin的历程-数据类型(2)
- 学习kotlin 记录笔记。----数据类型
- Kotlin基础教程-基本数据类型
- Android开发,Kotlin的了解与学习(二)-----Kotlin数据类型与Extensions的学习
- Kotlin入门第三课:数据类型
- 《Kotlin 极简教程 》第4章 基本数据类型与类型系统
- Kotlin入门教程系列(二) 基本数据类型 Number
- Kotlin - 基本数据类型
- Kotlin学习笔记2 : 变量常量与基本数据类型
- 分享下学习Kotlin的历程-变量/数据类型(1)
- Kotlin 学习之数据类型