一、when
1.1 when语句
相较于我们比较熟悉的Switch关键字,Kotlin的When关键字提供了一种更加灵活和简洁的结构,结合Lambda表达式用来进行条件的判断.
fun main() {
cases("Hello")
cases(1)
cases(0L)
cases(MyClass())
cases("hello")
}
fun cases(obj: Any) {
when (obj) {
1 -> println("One")
"Hello" -> println("Greeting")
is Long -> println("Long")
!is String -> println("Not a String")
else -> println("Unknown")
}
}
Greeting
One
Long
Not a String
Unknown
可以看到,在上面的when语句中对obj进行了分支的判断,由于入参的类型是Any,所以接受了各种类型的参数,可以是详细的某个数值的判断,也可以是简单的参数类型判断,也支持else操作符.
1.2 when表达式
class MyClass
fun main() {
println(whenAssign("Hello"))
println(whenAssign(3.4))
println(whenAssign(1))
println(whenAssign(MyClass()))
}
fun whenAssign(obj: Any): Any {
val result = when (obj) {
1 -> "One"
"Hello" -> 1
is Long -> false
else -> 42
}
return result
}
上面的whenAssign方法接受的入参和返参都是Any类型,使用when语句表达式对接收的obj入参进行相应判断并且反正不同类型的条件语句.可以看到,这里面的条件判断语句是默认返回42的。
在when语句中,是需要else表达式做所有条件的判断的.
二、Loop循环
Kotlin支持的循环模式有如下几种:for,while,do-while
2.1 for循环
fun main() {
val cakes = listOf("carrot", "cheese", "chocolate")
for (cake in cakes) {
println("Yummy,it's a $cake cake !")
}
}
Yummy,it's a carrot cake !
Yummy,it's a cheese cake !
Yummy,it's a chocolate cake !
写法与java的for循环很相似,迭代器遍历每个参数.
2.2 while和do-while
fun eatACake() = println("Eat a Cake")
fun bakeACake() = println("Bake a Cake")
fun main() {
var cakesEaten = 0
var cakesBaked = 0
while (cakesEaten < 5) {
eatACake()
cakesEaten++
}
do {
bakeACake()
cakesBaked++
} while (cakesBaked < cakesEaten)
}
while语句和do-while语句和我们之前所熟悉的循环逻辑也是一致的.while语句是需要语句块判断条件为true的时候执行,do-while是先执行语句块再判断条件.
2.3 Iterators迭代器
class Animal(val name: String)
class Zoo(private val animals: List<Animal>) {
operator fun iterator(): Iterator<Animal> {
return animals.iterator()
}
}
fun main() {
val zoo = Zoo(listOf(Animal("zebra"), Animal("lion")))
for (animal in zoo) {
println("Watch out,it's a ${animal.name}")
}
}
使用list的默认迭代器 对动物的名字进行输出.
Watch out,it's a zebra
Watch out,it's a lion
class Zoo(private val animals: List<Animal>) {
operator fun iterator(): Iterator<Animal> {
return object : Iterator<Animal> {
override fun next(): Animal {
return Animal("111")
}
override fun hasNext(): Boolean {
return true
}
}
}
}
fun main() {
val zoo = Zoo(listOf(Animal("zebra"), Animal("lion")))
for (animal in zoo) {
println("Watch out,it's a ${animal.name}")
}
}
我们也可以自己去实现迭代器进行集合的迭代逻辑.
三、Ranges区间
kotlin还提供了一系列工具用于区间的数据处理,kotlin的Ranges区间和Python中的步长很相似
for (i in 0..3) {
print(i)
}
print(" ")
for (i in 2..8 step 2) {
print(i)
}
print(" ")
for (i in 3 downTo 0) {
print(i)
}
print(" ")
- 第一个for循环从0循环遍历到3,输出0 1 2 3
- 第二个for循环从2循环遍历到8,输出2 4 6 8
- 第三个for循环从3到0倒序遍历,输出3 2 1 0
char数组也支持同样的操作.
for (c in 'a'..'d') {
print(c)
}
print(" ")
for (c in 'z' downTo 's' step 2) {
print(c)
}
print(" ")
abcd zxvt
in 关键字同样支持用在if语句中
val x = 2
if (x in 1..5) {
print("$x is in range from 1 to 5")
}
println()
if (x !in 6..10) {
print("x is not in range from 6 to 10")
}
2 is in range from 1 to 5
x is not in range from 6 to 10
四、相等关系检查
在kotlin中,使用==来比较结构是否相等.使用 === 来比较引用地址是否相等.
a==b 编译完之后等价于 if(a==null) b==null else a.equals(b)
val authors = setOf("Shakespeare", "Hemingway", "Twain")
val writers = setOf("Twain", "Shakespeare", "Hemingway")
val writes1 = setOf("Twain", "Shakespeare", "Hemingway")
val writes2 = writers
println(authors == writers)
println(authors === writers)
println(writers === writes1)
println(writes2 === writers)
true
false
false
true
- 第一个表达式返回true是因为调用了authors.equals(writes),sets几乎会忽略集合中元素的顺序
- 第二个表达式返回false是因为authors和writes不是同样的引用地址
- 第三个表达式返回false是因为虽然writes和writes1集合元素相等,但是两者指向得并不是相同的引用地址.
- 第四个表达式返回true是因为指向了同一个对象
五、多元表达式Conditional Expression
在kotlin中没有java的 a?b :c的三元表达式,相反,我们可以使用这种表达.
fun main() {
println(max(99, -42))
}
fun max(a: Int, b: Int) = if (a > b) a else b