基本类型
在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数和属性。 一些类型可以有特殊的内部表示——例如,数字、字符和布尔值可以在运行时表示为原生类型值,但是对于用户来说,它们看起来就像普通的类。 在本节中,我们会描述 Kotlin 中使用的基本类型:数字、字符、布尔值、数组与字符串。
数字
Kotlin 处理数字在某种程度上接近 Java,但是并不完全相同。例如,对于数字没有隐式拓宽转换(如 Java 中 int 可以隐式转换为long——译者注),另外有些情况的字面值略有不同。
Kotlin 提供了如下的内置类型来表示数字(与 Java 很相近):
Type | Bit width |
---|---|
Double | 64 |
Long | 64 |
Float | 32 |
Int | 32 |
Short | 16 |
Byte | 8 |
字面常量
数值常量字面值有以下几种:
- 十进制: 123
- Long 类型用大写 L 标记: 123L
- 十六进制: 0x0F
- 二进制: 0b00001011
注意: 不支持八进制
Kotlin 同样支持浮点数的常规表示方法:
- 默认 double:
123.5
、123.5e10
- Float 用
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
运算
Kotlin中的运算符被定义成相应类的类成员函数,通过复写相应运算符函数,可重载运算符功能。参见 运算符重载。
对于位运算,没有特殊字符来表示,而只可用中缀方式调用命名函数,例如:
val x = (1 shl 2) and 0x000FF000
这是完整的位运算列表(只用于 Int 和 Long):
-
shl(bits)
– 有符号左移 (Java 的<<
) -
shr(bits)
– 有符号右移 (Java 的>>
) -
ushr(bits)
– 无符号右移 (Java 的>>>
) -
and(bits)
– 位与 -
or(bits)
– 位或 -
xor(bits)
– 位异或 -
inv()
– 位非
字符
字符用 Char
类型表示。它们不能直接当作数字
字符字面值用单引号括起来:'1'
。 特殊字符可以用反斜杠转义。
我们可以显式把字符转换为 Int 数字:
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 显式转换为数字
}
布尔
布尔用 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>
// ……
}
Kotlin数组创建方法:
//创建数组,并赋值为1,2,3
val arrInt: Array<Int> = arrayOf(1, 2, 3)
//创建数组,长度为5,内容为空
val arrStringNulls: Array<String?> = arrayOfNulls<String>(5)
for (index in 0 until arrStringNulls.size) {
arrStringNulls[index] = "This is " + index
}
for (index in arrStringNulls.indices)
println("arrStringNulls[$index] = ${arrStringNulls[index]}")
//创建数组,长度为5,使用一个函数参数的工厂函数生产元素
val arrStringByFactroy: Array<String> = Array<String>(5, { i -> (i * i).toString() })
for (value in arrStringByFactroy)
println("value=$value")
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 = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
""".trimMargin()
通过 trimMargin() 函数去除前导空格,默认 |
用作边界前缀,但你可以选择其他字符并作为参数传入,比如 trimMargin(">")
。
val text = """
>Tell me and I forget.
>Teach me and I remember.
>Involve me and I learn.
>(Benjamin Franklin)
""".trimMargin(">")
变量
Kotlin的变量分为可变和不可变变量,和Java中是否采用final修饰的变量含义一样。
- 采用
val
声明的变量为不可变变量,即常量:
//编译期常量
const val tag: String = "MainActivity"
//常量
val tag: String = getString()
//等同于Java
final String tag = "MainActivity";
- 采用
var
声明的变量为可变变量:
var num: Int = 1
//等同于Java
int num = 1;
函数
Kotlin定义一个函数的格式如下:
访问控制符 fun 方法名(参数,参数,参数) : 返回值类型 {
···
···
}
- 访问控制符:Kotlin的访问控制符范围从大到小分别为:
public
、internal
、protected
、private
,不声明默认为public
;
Kotlin与Java函数的一个重大的区别就是:
Kotlin支持包级函数,即函数不依赖于类而存在,而在Java中,函数必须声明在类里面:
//包级函数
fun main(args: Array<String>){
}
//Java函数必须依赖类而存在
public class ClzFun{
public static void main(String[] args){
}
}
可变参数
Kotlin中,可变参数使用关键字 vararg
:
fun variousArgs(vararg args: String) {
for (arg: String in args)
println(arg)
}
//Java可变参数
public void variousArgs(String... args){
}
静态变量和静态函数
Kotlin中并没有像Java一样,提供 static
这个关键字,如果想在Kotlin中实现静态变量和静态函数,可以使用 companion object, companion object
后可以加上自定义的object名,也可以省略。
fun main(args: Array<String>) {
println(KotlinStatic.staticInt)
KotlinStatic.getInstance()
}
class KotlinStatic{
companion object StaticTest{
var staticInt: Int = 1
fun getInstance() : KotlinStatic{
return KotlinStatic()
}
}
}
//Java静态常量和静态函数
public class JavaStatic{
public static int staticInt = 1;
public static JavaStatic getInstance(){
return new JavaStatic();
}
}
对于在Kotlin中实现static变量和static方法,官方更推荐直接使用包级别的变量或函数来实现。因为如果使用 companion object
实现 static
功能,Kotlin在运行的时候,是会创建一个 companion object
实例对象,就相当于多了一些时间进行对象创建,初始化分配空间等操作。
附录
注意事项:
- Kotlin对于数字没有隐式拓宽转换(如 Java 中 int 可以隐式转换为long)
所以,对于下面这个例子,其是无法通过编译的:
val b: Byte = 1 // OK, 字面值是静态检测的
val i: Int = b // 错误
Kotlin没有办法将 Byte
赋值给 Int
类型,对于这种不同类型数值赋值,我们必须通过 显示转型 来拓宽数字:
val i: Int = b.toInt() // OK: 显式拓宽
每种数字类型支持如下的转换:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
运算符重载示例:
data class Counter(val x: Int) {
operator fun plus(inc: Int) = Counter(x + inc)
operator fun plus(inc: Counter): Counter {
return Counter(x + inc.x)
}
}
fun main(args: Array<String>) {
println(Counter(1) + Counter(3))
println(Counter(1) + 11)
}
本文大部分内容来自:https://hltj.gitbooks.io/kotlin-reference-chinese/content/txt/basic-types.html