Kotlin-基础篇
变量
在 Kotlin 中,所有变量的成员方法和属性都是一个对象。
声明常量
fun main(args: Array<String>) {
val a: Int = 1 // 立即初始化
val b = 2 // 推导出Int型
val c: Int // 当没有初始化值时必须声明类型
c = 3 // 赋值
println("a = $a, b = $b, c = $c")
}
变量:
fun main(args: Array<String>) {
var x = 5 // 推导出Int类型
x += 1
println("x = $x")
}
可空变量以及空值检查
使用一个返回可空值的函数:
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// 直接使用 x*y 会产生错误因为它们中有可能会有空值
if (x != null && y != null) {
// x 和 y 将会在空值检测后自动转换为非空值
println(x * y)
}
else {
println("either '$arg1' or '$arg2' is not a number")
}
}
fun main(args: Array<String>) {
printProduct("6", "7")
printProduct("a", "7")
printProduct("a", "b")
}
变量类型检查
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// obj 将会在这个分支中自动转换为 String 类型
return obj.length
}
// obj 在种类检查外仍然是 Any 类型
return null
}
常用的数据类型
数值类型
Kotlin
提供了如下内建数值类型(和 Java
很相似):
类型 | 字宽 |
---|---|
Double |
64 |
Float |
32 |
Long |
64 |
Int |
32 |
Short |
16 |
Byte |
8 |
字面值常量
主要是以下几种字面值常量:
–数型: 123
--长整型要加大写 L : 123L
--16进制:0x0f
--二进制:
0b00001011
注意不支持8进制
Kotlin 也支持传统的浮点数表示:
– 默认 Double : 123.5 , 123.5e10
– Float
要添加 f 或 F :123.5f
显示转换
每个数值类型都支持下面的转换:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
数值比较
数值比较必须是相同类型,还有注意就是 ==
和 ===
区别。
val a : Int = 1
val b : Float = 1f
//print( if(a == b) a else b) 类型不匹配
print( if(a == b.toInt()) a else b)
字符型
字符类型用 Char
表示。不能直接当做数值来使用。
val c : Char = '1'
// val c : Char = 1 类型不匹配
字符串
字符串是由 String
表示的。字符串是不变的。字符串的元素可以通过索引操作读取: s[i]
。字符串可以用 for 循环迭代:
for (c in str) {
println(c)
}
可以+
将字符串与其他类型的值连接起来组成字符串,但是第一个元素必须是字符串。注意在大多数情况下使用字符串模板或者原始字符串比字符串拼接更好。
val s = "abc" + 1
println(s + "def")
字符串字面量(String Literals)
Kotlin 有两种类型的字符串字面量 :一种是可以转义字符串(escaped string
),一种是原始字符串(raw string
)。转义字符串类似于Java String:
val s = "Hello, world!\n"
原始字符串的范围由"""
界定,可以包含任意字符和新行但不包括转义字符。
val text = """
for (c in "foo")
print(c)
"""
字符串模板
字符串可以包含模板表达式,比如说需要计算的代码段,它的结果可以和字符串拼接在一起。模板表达式以$
开始,随后既可以是变量名也可以是以大括号包含的任意表达式。
fun main(args: Array<String>) {
var a = 1
// 使用变量名作为模板:
val s1 = "a is $a"
a = 2
// 使用表达式作为模板:
val s2 = "${s1.replace("is", "was")}, but now is $a"
println(s2)
// 使用表达式作为模板
println("max of 0 and 42 is ${ if (a > b) a else b }")
}
转移字符串和原始字符串都支持模板,如果需要在原始字符串表达$
,可以这样:
val price = """
${'$'}9.99
"""
数组
数组在Kotlin
里面用Array
类表示,它提供了set()
和 get()
还有size
属性等等,同时还有[]
作为重载运算符。
创建一个Array
数组,可以使用 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() })
asc.forEach { println(it) }
控制语句
if
在 Kotlin
中,if
是表达式,比如它可以返回一个值。是除了(condition ? then : else)
之外的唯一一个三元表达式。
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// As expression
val max = if (a > b) a else b
if
分支可以作为块,最后一个表达是是该块的值:
val max = if (a > b){
print("Choose a")
a
}
else{
print("Choose b")
b
}
如果将 if
作为一个表达式,那么其else
分支不可少。
when
when
取代了传统语言的switch
,when
的用法将更加灵活。
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { //Note the block
print("x is neither 1 nor 2")
}
}
可以用 in 或者 !in 检查值是否值在一个集合中:
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
如果没有任何参数提供,那么分支的条件就是简单的布尔表达式,当条件为真时执行相应的分支:
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
for
for
的语句较为简单,与传统语言会较为相似。
for (item in collection) print(item)
for (i in 1..3) {
print(i)//Result:123
}
for (i in 6 downTo 0 step 2) {
print(i)//Result:6420
}
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
while
和传统语言一样。
跳转和返回
class Person(var name: String) {
}
fun main(args: Array<String>) {
val person = Person("e")
println("----retunr|break|continue----")
val f = fun() : String? {
val s = person.name ?: return null
return 1 .toString()
}
println(f()) // 1
for(i in 1 .. 2){
if(i != 1) println(i)
else break
}
for(i in 1 .. 2){
if(i != 1) println(i)//2
else continue
}
println("----retunr@label|break@label|continue@label----")
loop@ for (i in 1..10) {
for (j in i..10) {
if ( j == 2) break@loop
else println(j) // 1
}
}
loop@ for (i in 1..10) {
println("I:$i")
for (j in i..10) {
if ( j == 2) continue@loop
else println(j)
}
}
val t = fun() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop => return forEach
print(it) // 1245
}
print(" done with explicit label") // done with explicit label
}
t()
val g = fun() {
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return // local return to the caller of the anonymous fun, i.e. the forEach loop
print(value)
})
print(" done with anonymous function")
}
g()
}