【Kotlin】Kotlin学习一-基本类型
学而不思则罔,思而不学则殆
数字
整数Byte Short Int Long
类型 | 大小 | 最大值 | 最小值 |
---|---|---|---|
Byte | 8 | 27-1 (127) | -27(-128) |
Short | 16 | 215-1(32767) | -215(-32768) |
Int | 32 | 231-1(2147483647) | -231(-2147483648) |
Long | 64 | 263-1(9223372036854775807) | -263(-9223372036854775808) |
println("Byte Range = [${Byte.MIN_VALUE},${Byte.MAX_VALUE}]")//Byte Range = [-128,127]
println("Short Range = [${Short.MIN_VALUE},${Short.MAX_VALUE}]")//Short Range = [-32768,32767]
println("Int Range = [${Int.MIN_VALUE},${Int.MAX_VALUE}]")//Int Range = [-2147483648,2147483647]
println("Long Range = [${Long.MIN_VALUE},${Long.MAX_VALUE}]")//Long Range = [-9223372036854775808,9223372036854775807]
所有以未超出 Int 最大值的整型值初始化的变量都会推断为 Int 类型。如果初始值超过了其最大值,那么推断为 Long 类型。 如需显式指定 Long 型值,请在该值后追加 L 后缀。
显示指定类型:
val oneByte: Byte = 1 //byte
val oneShort: Short = 1 //long
val oneInt: Int = 1 //int
val oneLong:Long = 1 //long
val one = 1 // Int
val threeBillion = 3000000000 // Long
浮点数
对于以小数初始化的变量,编译器会推断为 Double 类型。 如需将一个值显式指定为 Float类型,请添加 f 或 F 后缀。 如果这样的值包含多于 6~7 位十进制数,那么会将其舍入。
val pi = 3.14 // Double
val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float,实际值为 2.7182817,舍弃了一部分精度
println(pi)//3.14
println(e)//2.7182818284
println(eFloat)//2.7182817
请注意,与一些其他语言不同,Kotlin 中的数字没有隐式拓宽转换(只有显示转换)。 例如,具有 Double 参数的函数只能对 Double 值调用,而不能对 Float 、 Int 或者其他数字值调用。
fun testNum() {
fun printDouble(d: Double) { println(d) }
val i = 1
val d = 1.1
val f = 1.1f
printDouble(d)//1.1
//printDouble(i)//错误,类型不匹配
//printDouble(f)//错误,类型不匹配
//需要显示转换类型才能调用
printDouble(f.toDouble())//1.100000023841858
printDouble(i.toDouble())//1.0
}
字面常量
数值常量字面值有以下几种(注意: 不支持八进制):
fun testNum() {
//十进制: 123
println(123)//123
//Long 类型用大写 L 标记: 123L
println(123L)//123
//十六进制: 0x0F
println(0x0F)//15
//二进制: 0b00001011
println(0b00001011)//11
}
Kotlin 同样支持浮点数的常规表示方法:
默认 double: 123.5 、 123.5e10
Float 用 f 或者 F 标记: 123.5f
println(123.5)//123.5
println(1.235e5)//123500.0
println(123.5f)//123.5
其中123.5e3 = 1.235 x 105
数字字面值中的下划线(自 1.1 起):
你可以使用下划线使数字常量更易读
fun testNum() {
val oneMillion = 1_000_000 //1000000
val creditCardNumber = 1234_5678_9012_3456L //1234567890123456
val socialSecurityNumber = 999_999_999L //999999999
val hexBytes = 0xFF_89_42_5A //4287185498
val bytes = 0b11111111_10001001_01000010_01011010 //4287185498
}
表达方式
第一组实验(Int?1000 和Int? 100)
第二组实验(Int 1000 和Int 100)
第三组实验(缓存)
JVM虚拟机的的优化,范围 -128 到 127之间有缓存(Java中一样):
== 两个等号意思与Java中的 equals 意思一样
=== 三个等号的意思,则比较的是内存地址
Int? 表示的Intgert对象,只有integer才是既可以有数值,又可以为 null
Int 不加?就是基本类型
同一性和相等性
同一性:是否是同一个对象
相等性:不同对象是否相等
显示转换
因此较小的类型不能隐式转换为较大的类型。 这意味着在不进行显式转换的情况下我们不能把 Byte 型值赋给一个 Int 变量。
val b: Byte = 1 // OK, 字面值是静态检测的
val i: Int = b // 错误
我们可以显式转换来拓宽数字
val b: Byte = 1
val i: Int = b.toInt() // OK:显式拓宽
print(i)//1
位运算
对于位运算,没有特殊字符来表示,而只可用中缀方式调用具名函数,例如:
运算法 | 说明 | java |
---|---|---|
shl(bits) | 有符号左移 | << |
shr(bits) | 有符号右移 | >> |
shr(bits) | 无符号右移 | |
and(bits) | 位与 | & |
or(bits) | 位或 | | |
xor(bits) | 位异或 | ^ |
inv() | 位非 | ~ |
字符
字符用 Char 类型表示。它们不能直接当作数字
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 显式转换为数字
}
布尔
布尔用 Boolean 类型表示,它有两个值: true 与 false 。若需要可空引用布尔会被装箱。
数组
使用库函数 arrayOf() 来创建一个数组并传递元素值给它,这样 arrayOf(1, 2, 3),创建了 array [1, 2, 3] 。
var ss = arrayOf(1, 2, 3)
println(ss.contentToString())//[1, 2, 3]
println(ss[1])//2
val asc = Array(5) { i -> (i * i).toString() }
println(asc.contentToString())//[0, 1, 4, 9, 16]
原生类型数组
CharArray,ByteArray,ShortArray,IntArray,LongArray,FloatArray,DoubleArray,BooleanArray
println(CharArray(5) { 'a' }.contentToString())
println(ByteArray(5) { 127 }.contentToString())
println(ShortArray(5) { 1 }.contentToString())
println(IntArray(5) { it }.contentToString())
println(LongArray(5) { (it * 2).toLong() }.contentToString())
println(FloatArray(5) { it.toFloat() }.contentToString())
println(DoubleArray(5) { it.toDouble() }.contentToString())
println(BooleanArray(5) { (it % 2) == 0 }.contentToString())
[a, a, a, a, a]
[127, 127, 127, 127, 127]
[1, 1, 1, 1, 1]
[0, 1, 2, 3, 4]
[0, 2, 4, 6, 8]
[0.0, 1.0, 2.0, 3.0, 4.0]
[0.0, 1.0, 2.0, 3.0, 4.0]
[true, false, true, false, true]
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
println(x.contentToString())//[5, 2, 3]
// 大小为 5、值为 [0, 0, 0, 0, 0] 的整型数组
val arr1 = IntArray(5)
println(arr1.contentToString())//[0, 0, 0, 0, 0]
// 例如:用常量初始化数组中的值
// 大小为 5、值为 [42, 42, 42, 42, 42] 的整型数组
val arr2 = IntArray(5) { 42 }
println(arr2.contentToString())//[42, 42, 42, 42, 42]
// 例如:使用 lambda 表达式初始化数组中的值
// 大小为 5、值为 [0, 1, 2, 3, 4] 的整型数组(值初始化为其索引值)
var arr3 = IntArray(5) { it * 1 }
println(arr3.contentToString())//[0, 1, 2, 3, 4]
字符串
原始字符串 使用三个引号( “”" )分界符括起来,内部没有转义并且可以包含换行以及任何其他字符
val text = """
for (c in "foo")
print(c)
"""
字符串字面值可以包含模板表达式 ,即一些小段代码,会求值并把结果合并到字符串中。 模板表达式以美元符( $ )开头,由一个简单的名字构成
val i = 10
println("i = $i") // 输出“i = 10”
或者用花括号括起来的任意表达式:
val s = "abc"
println("$s.length is ${s.length}") // 输出“abc.length is 3”