1.解构声明(Destructuring Declarations)
声明
val (name, age) = person
使用的时候
println(name)
println(age)
内部机制是下面这样
val name = person.component1()
val age = person.component2()
在for循环的时候还可以这样
for ((a, b) in collection) { ... }
a和b代表item的component1()和component2()
还可以代表函数
data class Result(val result: Int, val status: Status)
fun function(...): Result {
// computations
return Result(result, status)
}
// Now, to use this function:
val (result, status) = function(...)
在map中使用
for ((key, value) in map) {
// do something with the key and the value
}
我们看下标准库也提供了解构声明
operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = entrySet().iterator()
operator fun <K, V> Map.Entry<K, V>.component1() = getKey()
operator fun <K, V> Map.Entry<K, V>.component2() = getValue()
还可以在lambda表达式中使用
map.mapValues { entry -> "${entry.value}!" }
map.mapValues { (key, value) -> "$value!" }
{ a -> ... } // one parameter
{ a, b -> ... } // two parameters
{ (a, b) -> ... } // a destructured pair
{ (a, b), c -> ... } // a destructured pair and another parameter
参数有时候可以省略,使用”_”
map.mapValues { (_, value) -> "$value!" }
2.Collections
kotlin和其他语言不一样,提供可变和不可变的集合,比如MutableList和List,分析下面的代码
val numbers: MutableList<Int> = mutableListOf(1, 2, 3)
val readOnlyView: List<Int> = numbers
println(numbers) // prints "[1, 2, 3]"
numbers.add(4)
println(readOnlyView) // prints "[1, 2, 3, 4]"
readOnlyView.clear() // -> does not compile
val strings = hashSetOf("a", "b", "c", "c")
assert(strings.size == 3)
kotlin没有提供相关的构造函数,需要使用标准库中的函数,比如listOf(),mutableListOf(),setOf(),mutableSetOf()等
分析下面的代码
val items = listOf(1, 2, 3, 4)
items.first() == 1
items.last() == 4
items.filter { it % 2 == 0 } // returns [2, 4]
val rwList = mutableListOf(1, 2, 3)
rwList.requireNoNulls() // returns [1, 2, 3]
if (rwList.none { it > 6 }) println("No items above 6") // prints "No items above 6"
val item = rwList.firstOrNull()
看下Map的创建
val readWriteMap = hashMapOf("foo" to 1, "bar" to 2)//to关键字
println(readWriteMap["foo"]) // prints "1"
val snapshot: Map<String, Int> = HashMap(readWriteMap)
3.Ranges
Ranges比较好理解,看代码就可以理解
if (i in 1..10) { // equivalent of 1 <= i && i <= 10
println(i)
}
for (i in 1..4) print(i) // prints "1234"
for (i in 4..1) print(i) // prints nothing,这里需要注意4..1不会执行
for (i in 4 downTo 1) print(i) // prints "4321",上面的语句正确写法
for (i in 1..4 step 2) print(i) // prints "13"
for (i in 4 downTo 1 step 2) print(i) // prints "42"
for (i in 1 until 10) { // i in [1, 10), 10 is excluded
println(i)
}
4.类型检查和类型转换
也很好理解,通过代码来理解下
if (obj is String) {
print(obj.length)
}
if (obj !is String) { // same as !(obj is String)
print("Not a String")
}
else {
print(obj.length)
}
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
不安全的类型转换
val x: String = y as String //因为y如果是null,就不会转换成String
val x: String? = y as String?//正确写法
安全的类型转换
val x: String? = y as? String
5.This表达式
这个也很好理解,通过下面代码来理解
class A { // implicit label @A
inner class B { // implicit label @B
fun Int.foo() { // implicit label @foo
val a = this@A // A's this
val b = this@B // B's this
val c = this // foo()'s receiver, an Int
val c1 = this@foo // foo()'s receiver, an Int
val funLit = lambda@ fun String.() {
val d = this // funLit's receiver
}
val funLit2 = { s: String ->
// foo()'s receiver, since enclosing lambda expression
// doesn't have any receiver
val d1 = this
}
}
}
}
6.Equality
kotlin包括两种
===
引用相同,指向同一个对象==
结构相同,equals()
6.1 引用相同
===
和!==
是引用相同和引用不相同。
6.2 结构相同
==
和!=
是结构相同和结构不相同
a == b
//等同于
a?.equals(b) ?: (b === null)