变量的声明
在 Kotlin 中,使用val
定义不可变变量,使用var
定义可变变量,定义的格式如下:
[val|var] [变量名][: 变量类型] = [变量值]
变量名可以随意取,但不能以数字开头,也不能包含特殊字符,使用关键字时需要加反引号``(英文输入法,在键盘左上角Esc
下方的~
键)。Kotlin 可以使用中文命名变量,但是非常不推荐这样做,IDEA 也给出了警告。
fun main() {
val 你好Kotlin = "Hello Kotlin."
println(你好Kotlin)
}
Hello Kotlin.
这里定义一个String
类型的名为name
的可变变量,和一个Int
类型的名为id
的不可变变量:
fun main() {
// 定义 String 类型的可变变量,并赋值为 "A"
var name: String = "A"
// 将变量的值改为 "B"
name = "B"
// 定义 Int 类型的不可变变量,并赋值为 0
val id: Int = 0
// id = 1 这样是错误的,val修饰的变量一旦赋值就不能更改
}
Kotlin 支持自动类型推断,因此,在能够推断出类型的情况下,可以不用指定类型:
fun main() {
var name = "A"
// 在没有赋值的情况下,无法推断类型,所以得指出类型
val id: Int
id = 1
}
Kotlin 变量也可以声明在main
函数外部:
val id = 0
fun main() {
println(id)
}
0
基本类型
数字
定义
在数字类型中,包含有符号(负号)类型Byte
、Short
、Int
、Long
、Float
、Double
(类型间差异主要在于取值范围,参考。如果给出的值超出范围,IDEA 将直接标红),和对应的无符号类型UByte
、UShort
、UInt
、ULong
。
Float
类型必须在数值末尾加F
或f
,Long
类型则可以选择性地在末尾加上L
或l
(由于小写l
与数字1
长得太像,一般用大写),所有的无符号类型必须加上U
或u
,ULong
可以选择性地在末尾加上L
(不能是小写)。
fun main() {
val byte: Byte = 1
val short: Short = 1
val int: Int = 1
val long: Long = 1
val float: Float = 1.0f
val double: Double = 1.0
val uByte: UByte = 1u
val uShort: UShort = 1u
val uInt: UInt = 1u
val uLong: ULong = 1u
}
当没有特别指出类型时,整数一般会自动推断为Int
,而小数会是Double
,数字末尾标记F
或f
会是Float
,而U
或u
会是uInt
。
fun main() {
val int = 1
val float = 1.0f
val double = 1.0
val uInt = 1u
}
Kotlin 支持在数字间加上下划线_
方便阅读,下划线可以加在随意的数字之间的位置,但一般还是遵循常用的分割方式
fun main() {
val largeInt = 1_000_000_000
// 你可以随意加
val int = 1_0
}
比较大小
可以使用>
、<
、==
(不能用于不同类型)、>=
、<=
比较数字大小:
fun main() {
println(1 > 0f)
println(1 < 2L)
println(1 == 1)
println(1 >= 0f)
println(1 <= 2L)
}
true
true
true
true
true
布尔
布尔类型Boolean
只有两个值:true
或false
。
fun main() {
val booleanTrue: Boolean = true
val booleanFalse = false
}
多数时候,Boolean
会和&&
(与)、||
(或)、!
(非)一起使用。
&&
可连接两个Boolean
,只有两者都为true
,整体的值才为true
。当两者都为true
时,整体为true
;当一个为true
,一个为false
时,整体为false
;当两者都为false
时,整体为false
。val TRUE = true val FALSE = false fun main() { println(TRUE && TRUE) // true println(TRUE && FALSE) // false println(FALSE && FALSE) // false }
true false false
||
可连接两个Boolean
,只要有一个值为true
,整体的值才为true
。当两者都为true
时,整体为true
;当一个为true
,一个为false
时,整体为true
;当两者都为false
时,整体为false
。val TRUE = true val FALSE = false fun main() { println(TRUE || TRUE) // true println(TRUE || FALSE) // true println(FALSE || FALSE) // false }
true true false
!
放置于Boolean
前,会使整体变为另一个值,!true
整体为false
,!false
整体为false
。val TRUE = true val FALSE = false fun main() { println(!TRUE) // false println(!FALSE) // true }
false true
字符
字符是指代表一个符号的内容(不一定只有一个符号),使用单引号''
修饰。
fun main() {
val char: Char = 'a'
}
单个反斜杠\
作为转义字符使用,和一些字符结合会成为单个字符,具体可参考:
- 反斜杠与
t
组成制表符:fun main() { val tab = '\t' print(tab) print("Hello") }
Hello
- 反斜杠与
n
组成换行符:fun main() { val enter = '\n' print(enter) print("Hello") }
Hello
- 单个反斜杠并不会表示反斜杠,需要用一对
\\
fun main() { val char = '\\' print(char) }
\
- 在双引号
""
中使用双引号"
字符会导致句意混乱,需要使用\
辅助:fun main() { val string: String = "\"" println(string) }
"
字符串
字符串由一个或多个字符组成,用双引号""
或者""" """
(多行)修饰。
当你输入"""
并回车后,trimIndent()
函数会自动加上,它会去掉首尾("""
所在的行)空行和缩进。
fun main() {
var string: String = "Hello Kotlin."
println(string)
string = """
Hello
Kotlin
""".trimIndent()
println(string)
}
Hello Kotlin.
Hello
Kotlin
字符串模板
在 Kotlin 中,可以很自然地使用+
将字符串与字符串或其他类型拼接起来:
fun main() {
val hello = "Hello"
val name = "Kotlin"
println(hello + " " + name)
}
Hello Kotlin
我们也可以在字符串中使用美元符$
实现拼接:
fun main() {
val hello = "Hello"
val name = "Kotlin"
println("$hello $name")
}
Hello Kotlin
为了将变量名与字符串区分开,必要时需要加上花括号{}
fun main() {
val dog = "dog"
println("${dog}s")
}
dogs
数组
定义
你可以使用arrayOf
函数定义一个数组:
fun main() {
val array = arrayOf(1, 2)
print(array)
}
[Ljava.lang.Integer;@7291c18f
可以看到我们打印出了一个看不懂的东西,单看整体其实可以理解为该数组的唯一标识。通过查询可以知道一个[
表示这是一个一维数组,以此类推,L
表名后面的java.lang.Interger
是一个引用类型,而@
后边的是哈希码。
如果要打印出数组中值,可以使用joinToString()
函数,它会将数组元素拼接为字符串:
fun main() {
val array = arrayOf(1, 2)
println(array.joinToString())
}
1, 2
Note:有些函数需要用
.
调用,例如数组的joinToString()
这是定义在数组类中的函数;而有些可以直接写函数名,这是像main
一样的顶层函数(Top Level Function)。
你可以在数组中放任意的内容:
fun main() {
arrayOf(1, 2, "3")
arrayOf( arrayOf(1, 2) , 3)
}
访问元素
数组可以用方括号[]
配合下标(Index)访问指定的元素,数组中的元素下标从0
开始依次递增,当我们要获取第一个元素的值时,我们需要使用0
。
fun main() {
val array = arrayOf("你", "好")
println(array[0])
}
你
当下标超出数组元素下标范围时,会引起异常java.lang.ArrayIndexOutOfBoundsException
:
fun main() {
val array = arrayOf("你", "好")
println(array[2])
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
at ink.awning.MainKt.main(Main.kt:6)
at ink.awning.MainKt.main(Main.kt)
类型转换
- 数字与
String
类型之间的转换可以用toXXX()
(XXX
为要转换的类型)来实现,例如String
转为Int
使用toInt()
:fun main() { val string = "11" val number = string.toInt() // IDEA 会标红,鼠标放在上面会提示 // Operator '==' cannot be applied to 'String' and 'Int' println(string == 11) // 无法比较 // 此时可以正常比较 println(number == 11) // true // 也可以写在一行 println(string.toInt() == 11) // true }
- 使用
as
关键字,一般是用于子父类之间或泛型的转化,如果无法转化会抛出异常。fun main() { // 子父类,MutableList 继承自 List val mutableList = mutableListOf(1, 2) val list = mutableList as List<Int> println(list) // 同为 List,泛型转换为其他类型 val intList = listOf(1, 2, 3) val stringList = intList as List<Double> stringList.forEach { print(it); print(", ") } }
Note:
as
关键字还可以用于导包时起别名:import ink.awning.ClassName as NewClassName
。
类型判断
可以使用is
判断某一变量是否为某一类型,!is
则相反:
fun main() {
val string: Any = ""
println(string is String)
println(string !is Int)
}
Note:
Any
表示该变量可以为任意类型。