What is Kotlin
?
Kotlin是JVM和Android的实用编程语言,结合了OO和功能特性,专注于互操作性,安全性,清晰度和工具支持。
本文记录自己学习kotlin
认为需要记录的重点,如果需要详细学习,请点击Kotlin中文文档学习。
基本类型
在 Kotlin 中,所有变量的成员方法和属性都是一个对象。一些类型是内建的,它们的实现是优化过的,但对用户来说它们就像普通的类一样。
- 数值类型
Kotlin 处理数值的方法和 java 很相似,但不是完全一样。比如,不存在隐式转换数值的精度,并且在字面上有一些小小的不同 。Kotlin 提供了如下内建数值类型(和 java 很相似):
类型 | 字宽 | |
---|---|---|
Double | 双精度浮点数 | 64 |
Float | 浮点数 | 32 |
Long | 长整型 | 64 |
Int | 整形 | 32 |
Short | 短整型 | 16 |
Byte | 字节 | 8 |
在Kotlin
中,短类型,不会隐式转化为长类型,这意味着我们必须显式转换才能把 Byte
赋值给 Int
。
error:
val b: Byte = 1 // OK, literals are checked statically
val i: Int = b //ERRO
right:
val i: Int = b.toInt()//显示转换
我们可以通过显式转换把数值类型提升 。每个数值类型都支持下面的转换:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
Kotlin支持标准的运算表达式,关于位运算,kotlin
没有提供特殊的操作符,只是提供了可以叫中缀形式的方法,比如:
val x = (1 shl 2) and 0x000FF000
下面是全部的位运算操作符(只可以用在 Int
和 Long
类型):
shl(bits)
– 带符号左移 (相当于 Java’s<<
)shr(bits)
– 带符号右移 (相当于 Java’s>>
)ushr(bits)
– 无符号右移 (相当于 Java’s>>>
)and(bits)
– 按位与or(bits)
– 按位或xor(bits)
– 按位异或inv(bits)
– 按位翻转
println(1 shl 3)//打印结果为8
- 字符类型
字符类型用Char
表示,不能直接当做数值使用:
fun check(c: Char) {
if (c == 1) { //ERROR: 类型不匹配,这里会提示
//...
}
}
字符是由单引号包裹的’1’,特殊的字符通过反斜杠\转义,下面的字符序列支持转义:\t,\b,\n,\r,’,”,\和$。编码任何其他字符,使用 Unicode 转义语法:\uFF00。
我们可以将字符显示的转义为Int数字:
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() //显示转换为数值类型
}
- 布尔值
只有true
和false
布尔值的内建操作包括|| – lazy disjunction && – lazy conjunction
- 数组
Arrays在 Kotlin 中由 Array
类表示,有 get
和 set
方法(通过运算符重载可以由[]调用),以及 size
方法,以及一些常用的函数:
class Array<T> private () {
fun size(): Int
fun get(index: Int): T
fun set(Index: Int, value: T): Unit
fun iterator(): Iterator<T>
//...
}
给库函数
arrayOf()
传递每一项的值来创建Array,arrayOf(1, 2, 3)
创建了一个[1, 2, 3] 这样的数组。var arr1 = arrayOf(1,2,3,4,5) //等价于[1,2,3,4,5] for (v in arr1){ print(v) print("\t") } var arr2 = arrayOf("0","2","3",'a',32.3f) for (v in arr2){ print(v) print("\t") }
输出结果为:
1 2 3 4 5 0 2 3 a 32.3
也可以使用库函数
arrayOfNulls()
用于创建一个指定数据类型且可以为空元素的给定元素个数的数组 。例:var arr3 = arrayOfNulls<Int>(3) //如若不予数组赋值则arr3[0]、arr3[1]、arr3[2]皆为null for(v in arr3){ print(v) print("\t") } println() //为数组arr3赋值 arr3[0] = 10 arr3[1] = 20 arr3[2] = 30 for(v in arr3){ print(v) print("\t") }
输出结果为:
null null null 10 20 30
或者通过指定Array大小并提供一个迭代器
- 使用一个工厂函数
Array()
,它使用数组大小和返回给定其索引的每个数组元素的初始值的函数。Array()
=> 第一个参数表示数组元素的个数,第二个参数则为使用其元素下标组成的表达式// 创建一个 Array<String> 内容为 ["0", "1", "4", "9", "16"] val asc = Array(5, {i -> (i * i).toString() })
- 字符串
Kotlin 有两种类型的 string :一种是可以带分割符的,一种是可以包含新行以及任意文本的。带分割符的 string 很像 java 的 string:
val s = "Hello World!\n"
整行String 是由三个引号包裹的(“””),不可以包含分割符但可以包含其它字符:
val text = """
for (c in "foo")
print(c)
"""
打印结果为
for (c in "foo")
print(c)
- 通配符$
字符串可以包含模板表达式。一个模板表达式由一个 $ 开始并包含另一个简单的名称:
val i = 10
val s = "i = $i" // 识别为 "i = 10"
或者是一个带大括号的表达式:
val s = "abc"
val str = "$s.length is ${s.length}" //识别为 "abc.length is 3"
流程控制
if 表达式
if除了除了传统的用法之外,还可以用作表达式
//传统用法
var max = a
if (a < b)
max = b
//带 else
var max: Int
if (a > b)
max = a
else
max = b
//作为表达式
val max = if (a > b) a else b
原来在java中的写法,在kotlin
中报错
var numA = 2
var numB: Int = (numA > 2) ? 3 : 5
//错误
when 表达式
when取代了 C 风格语言的 switch 。最简单的用法像下面这样
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { //Note the block
print("x is neither 1 nor 2")
}
}
在其它分支都不匹配的时候默认匹配 else 分支。如果把 when 做为表达式的话 else 分支是强制的,除非编译器可以提供所有覆盖所有可能的分支条件。
如果有分支可以用同样的方式处理的话,分支条件可以连在一起,相当于switch
语句中不适用break
跳转语句:
when (x) {
0,1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
when 可以用任意表达式作为分支的条件,也可以用in或!in判断是否在一个集合当中,只适用于数值类型,用is判断是否是某个类型。
fun describe(obj: Any): String =
when (obj) {
1 -> "one"
"hello" -> "gretting"
is Long -> "long"
!is String -> "Not a string"
else -> "unknown"
}
for 循环
for 循环通过任何提供的迭代器进行迭代。语法是下面这样的:
for (item in collection)
print(item)
内容可以是一个语句块
for (item: Int in ints){
//...
}
- 新增规则,去满足for(初始值;条件;增减步长)
递增:until
until
[n,m)= >即大于等于n,小于m
例:
// 循环5次,且步长为1的递增 for (i in 0 until 5){ print("i => $i \t") }
输出结果为
i => 0 i => 1 i => 2 i => 3 i => 4
递减:
downTo
downTo[n,m]
=> 即小于等于n,大于等于m ,n > m
例:
// 循环5次,且步长为1的递减 for (i in 15 downTo 11){ print("i => $i \t") }
输出结果为:
i => 15 i => 14 i => 13 i => 12 i =>
递增:符号
..
..[n,m]
=> 即大于等于n,小于等于m
和
until
的区别,一个包区间,一个闭区间,..
更简单吧!例:
print("使用 符号`..`的打印结果\n") for (i in 20 .. 25){ print("i => $i \t") } println() print("使用until的打印结果\n") for (i in 20 until 25){ print("i => $i \t") }
输出结果为:
使用 符号`..`的打印结果 i => 20 i => 21 i => 22 i => 23 i => 24 i => 25 使用until的打印结果 i => 20 i => 21 i => 22 i => 23 i => 24
步长:step
例:
for (i in 10 until 16 step 2){ print("i => $i \t") }
输出结果为:
i => 10 i => 12 i => 14
- 迭代
使用数组的indices属性遍历
例:
var arrayListTwo = arrayOf(1,3,5,7,9) for (i in arrayListTwo.indices){ println("arrayListTwo[$i] => " + arrayListTwo[i]) }
输出结果为:
arrayListTwo[0] => 1 arrayListTwo[1] => 3 arrayListTwo[2] => 5 arrayListTwo[3] => 7 arrayListTwo[4] => 9
使用数组的withIndex()方法遍历
例:
var arrayListTwo = arrayOf(1,3,5,7,9) for ((index,value) in arrayListTwo.withIndex()){ println("index => $index \t value => $value") }
输出结果为:
index => 0 value => 1 index => 1 value => 3 index => 2 value => 5 index => 3 value => 7 index => 4 value => 9
使用列表或数组的扩展函数遍历
- 数组或列表有一个成员或扩展函数
iterator()
实现了Iterator<T>
接口,且该接口提供了next()
与hasNext()
两个成员或扩展函数- 其一般和
while
循环一起使用
可以查看
Array.kt
这个类。可以看见其中的iterator()
函数,而这个函数实现了Iterator
接口。/** * Creates an iterator for iterating over the elements of the array. */ public operator fun iterator(): Iterator<T>
查看
Iterator.kt
这个接口类,这个接口提供了hasNext()
函数和next()
函数。public interface Iterator<out T> { /** * Returns the next element in the iteration. */ public operator fun next(): T /** * Returns `true` if the iteration has more elements. */ public operator fun hasNext(): Boolean }
例:
var arrayListThree = arrayOf(2,'a',3,false,9) var iterator: Iterator<Any> = arrayListThree.iterator() while (iterator.hasNext()){ println(iterator.next()) }
输出结果为:
2 a 3 false 9
终上所述就是
for
循环语句常用的用法。
while循环
while 和 do…while 像往常那样
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在这是可见的