基础-基本类型
Kotlin官网:Basics-Basic Types
按照官网的说法,everything is an object
数值型在运行时会有特殊处理,但对于用户来说没有区别,所有数值型都可以类比成Java中的包装类,可以调用方法和属性。其中可空和不可空的基本类型在引用上有些不同。
数的类型
6种数值型特性和Java类似
Type | Bit width |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
注意都是大写开头。
字面值
和Java区别不大
整形10进制是字面值,16进制0x,2进制0b
*不支持8进制表示
Long类型用”L”大写L作为后缀
val a = 1 // Int
val b = 0xFF // 16进制
val c = 0b00001101 //2进制
val b = 1L // Long
Double为字面值
Float加f或F后缀
val a = 123.5 // Double
val b = 123.5e10 // Double
val c = 123.6F // Float
下划线
Kotlin支持使用”_”下划线分割,不影响字面值,类似于金额中的”,”分割
比如val a = 1_000_000,就是val a = 1000000,只是方便阅读,不会影响程序执行
val b = 123_456L
val c = 0xFF_A0
val d = 0b0000_1101
类型含义
比较分为”==“和”===“,==比较的是值相等,===比较的是引用相等
这里涉及到Kotlin的装箱,当声明为”可为空”时,会进行装箱,此时会导致引用的变化
例如:
val a: Int = 10000
val b: Int = a
val c: Int = a
print(b == c) // Prints ‘true’
print(b === c) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA == anotherBoxedA) // Prints ‘true’
print(boxedA === anotherBoxedA) // Prints ‘false’
显式转换
和Java不同,Kotlin不支持隐式的向上转型,所有的转换都必须显的声明,这个比较好理解,都当做对象使用,自然不能隐式互相转换。
任何数值都带有转换成其他类型的toXXX()方法,XXX为转换的目标类型,比如要将Int转成Long
val a = 1 //Int
val b = a.toLong() //Long
支持不同类型的混合计算,这里的原理和Java不同。
在Java中,小范围值和大范围值计算是先将小范围值隐式向上转型后再和大范围值运算
int a = 1 + 2L;
在Java中是先将1转成1L再和2L相加,由于是自动完成的,用户感知不到
在Kotlin中不同类型的混合计算是通过调用重载的运算符方法实现的
val a = 1 + 2L
这里实际上是调用了1这个Int对象的plus方法
public operator fun plus(other: Long): Long
将2L作为参数传进这个方法,得到的val a实际是plus方法的返回值。
public operator fun plus(other: Long): Long
val a = 1 + 2L这句实际上等价于
val a = 1.plus(2L)
运算
数值支持基本的数学运算符,支持运算符重载。
Kotlin中没有位运算符,但是有位运算方法,使用中缀函数(infix)的形式实现
Java中位运算对应的Kotlin方法
运算符 | 含义 |
---|---|
shl | 左移 |
shr | 右移 |
ushr | 无符号右移 |
and | 与 |
or | 或 |
xor | 异或 |
inv | 置反 |
记起来也很方便,就是缩写,sh = shift, l = left, r = right, u = unsigned
除了inv置反以外,其他位运算都可以写成方法和参数的形式,或者运算符号的形式
inv写成调用方法的形式,其他位运算按照普通运算符号写即可
val a = 1
val b = a.inv() //置反
val c = b shl a // b左移a位
val d = b.shl(a) // 和 b shl a 等价
浮点数比较
普通数值比较和Java是相同的
运算符 | 含义 |
---|---|
== | 相同 |
!= | 不同 |
< | 小于 |
< | 大于 |
<= | 小于等于 |
>= | 大于等于 |
Kotlin额外支持范围a..b,如x in a..b,x !in a..b
val a = 1
println(a in 0..1) //true
println(a !in 0..1) //false
当浮点类型作为对象来使用时,也就是作为Any调用equals方法,或者作为Comparable调用ompareTo方式时,在Kotlin中有些特别
- NaN和NaN相等
- NaN大于任何其他浮点数,包括正无穷POSITIVE_INFINITY
- -0.0小于0.0
字符型(Char)
和Java不同,Kotlin中字符型不能直接当做数字使用,比如直接和数字判断相等会报错
val c = 'a'
println(c==10) //报错
使用方法和Java完全相同,单括号声明变量值,支持转义字符,支持’\uFF00’的Unicode写法。
转义字符:\t, \b, \n, \r, \’, \”, \\ ,\$
Char也有toXXX()转数字方法,需要当数字用时显式转换即可,特性和数字型差不多,也有装箱后引用变化的问题
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)
和Java基本相同,字面值”true”,”false”,装箱特性和数字相同。
布尔类型支持”||”,”&&”,”!”,不支持”|”和”&”
数组
Kotlin中使用Array<T>类表示Java中的T[]数组,重载了”[]”运算符实现a[i]形式的下标访问,添加了size属性(Java中的length)
创建方法可以使用lib中的函数(arrayOf),或者直接创建Array类
val a = arrayOf("1","2","3")
val b = Array(3, { it.toString() })
println(a.joinToString(","))
println(b.joinToString(","))
输出结果:
1,2,3
0,1,2
Java中T[]类型数组可以赋值给Object[]型变量,如下是正确的
String[] a = new String[0];
Object[] b = a;
而在Kotlin中,Array<T>型的实例不能赋值给声明成Array<Any>的变量,但是能赋值给Array<out Any>
val a:Array<String> = arrayOf("1","2","3")
val b:Array<Any> = a //报错无法编译
val c:Array<out Any> = a //正常
基本类型有对应的无需装箱的XXXArray类,和Array没有继承关系,用法相同
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
字符串
和Java类似,不可变,字面值为双引号,支持转义字符。
不同:
支持下标访问,支持for循环,可以看做一个CharArray。
支持原始字符串,用”“”三个引号括起来,不支持转义字符,支持换行。
有去缩进方法trimMargin(),默认使用”|”作为标记,可以自定义标记。
fun main(args: Array<String>) {
val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
"""
println(text)
println(text.trimMargin())
println("""
(======
(Tell me and I forget.
(Teach me and I remember.
(Involve me and I learn.
((Benjamin Franklin)
""".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)
======
Tell me and I forget.
Teach me and I remember.
Involve me and I learn.
(Benjamin Franklin)
支持字符模板,支持变量,格式为”$变量名“,支持表达式,格式为”${表达式}”
val i = 10
val s = "i = $i" // evaluates to "i = 10"
val s2 = "i+1 = ${i+1}" // evaluates to "i+1 = 11"
原始字符串也支持模板,所以在不支持转义字符的情况下可以用模板实现同样效果
val price = """
${'$'}9.99
"""