kotlin-第四章(高级特性)
2020-11-21 本文已影响0人
JuliusL
- 解构
- 循环和操作符
- 运算符重载
- 作用域函数
- 中缀表达式
- SDL
13:解构
operator:将一个函数标记为重载一个操作符,或者实现一个约定
可以自动将一个对象拆解成一组变量,分别赋值
class User(var age: Int, var name: String) {
//component是固定写法:后必须跟一个数字
operator fun component1() = age
operator fun component2() = name
}
fun main() {
val user = User(18, "zhang san")
//解构:就是把一个对象的属性拿出来,分别赋值给一组变量
//这组变量用括号括起来
val (age, name) = user
println(age)
println(name)
}
解构更常用与遍历一个map的时候
val map = mapOf<String,String>("key" to "key","value" to "value")
for ((k,v) in map ){
println("$k-----$v")
}
14:循环
for (i in 1..10){
println(i)
}
for (i in 1 until 10){
println(i)
}
for (i in 10 downTo 1){
println(i)
}
for (i in 1..10 step 2){
println(i)
}
repeat(10){
println(it)
}
//-------- 集合 ----------
val list = arrayListOf<String>("a","b","c","d")
//遍历集合的元素
for (str in list){
println(str)
}
//通过解构为每个元素赋值
for ((index,str) in list.withIndex()){
println("第${index}个元素是$str")
}
15:集合操作符
val a = arrayListOf("4", "0", "7", "i", "f", "w", "0", "9")
val index = arrayListOf(5, 3, 9, 4, 8, 3, 1, 9, 2, 1, 7)
index
.filter {
it < a.size
}
.map {
a[it]
}
.reduce { s, s1 ->
"$s$s1"
}
.also {
println("密码是:$it")
}
自定义集合操作符
fun main() {
val list = listOf(1, 2, 3, 5)
list.convert {
it+1
}.forEach{
println(it)
}
}
inline fun <T, E> Iterable<T>.convert(action: (T) -> E): Iterable<E> {
val list: MutableList<E> = mutableListOf()
for (item in this) list.add(action(item))
return list
}
16:作用域函数
run{...}
with(T){...}
let{...}
apply{...}
also{...}
- kotlin内置的一系列可以对数据做变换的函数,它们与集合操作符很相似,但是集合操作符只能用于集合的数据变换,而作用域函数可以运用于所有对象。
let和run
- kotlin中lambda如果只有一个参数,可省略该参数,用it去指代它
- let和run都会返回闭包的执行结果,区别在于let有闭包参数,而run没有
val user = User("zhang san")
//let和run都会返回闭包的执行结果,区别在于let有闭包参数,而run没有
val letResult = user.let { user ->
"let::${user.javaClass}"
}
println(letResult)
val runResult = user.run {
"run::${this.javaClass}"
}
println(runResult)
also和apply
- also和apply都不返回闭包的执行结果,区别在于also有闭包参数,而apply没有
//also和apply都不返回闭包的执行结果,区别在于also有闭包参数,而apply没有
user
.also {
println("${it.javaClass}")
}.apply {
println("${this.javaClass}")
}.name = "li si"
takeIf和takeUnless
- takeIf的闭包返回一个判断结果,为false时,takeIf函数会返回空
- takeUnless 与 takeIf刚好相反,闭包的判断结果,为true返回为空
//takeIf的闭包返回一个判断结果,为false时,takeIf函数会返回空
//takeUnless 与 takeIf刚好相反,闭包的判断结果,为true返回为空
user
.takeIf {
it.name.length > 0
}?.also {
println("姓名为:${it.name}")
} ?: println("姓名为空")
user
.takeUnless {
it.name.length > 0
}?.also {
println("姓名为空")
} ?: println("姓名为:${user.name}")
with
with比较特殊,不是以扩展方法的形式存在的,而是一个顶级函数
//with比较特殊,不是以扩展方法的形式存在的,而是一个顶级函数
with(user){
this.name = "haha"
}
常用操作符
image.pngimage.png
17:运算符重载和中缀表达式
kotlin中有120+个运算符,当运算符不够的时候,需要用中缀表达式。
定义中缀表达式
- 用infix关键字修饰一个函数
在kotlin中有一个非常特殊的语法,如果函数的函数名前面有一个点,点的前面是一个类型的时候,这时候,该类型称为函数的接收者,换言之,只有该类型才可调用该函数。
-
一个函数只有用于两个角色是类似的对象时才将其声明为中缀表达式。
推荐示例:and 、to、zip
反例:add -
如果一个方法会改动其接收者,则不要声明为中缀表达式
你好,请问一下关于重载运算符,rangeTo 是如何与.. 进行对应的?
作者回复: 运算符与代码是语言设计层面的,在编译期抽象语法树分析的时候对应起来的。
18:反引号【`】
- 在kotlin中可以用反引号解决关键词冲突的问题
- 可以将一个不合法的字符变为合法的
fun `123`(){}
fun ` `(){println("123")}
fun ` `(){}
fun main() {
//该特性一般不会去使用
//除非想杜绝别人在java中调用这些函数
//用kotlin的优势,屏蔽了java的调用
` `()
}
kotlin中对象的比较
kotlin的【==】 等价于 java的【equals】
kotlin的【===】 等价于 java的【==】
类型链接【typealias】
将一个类型完全映射为另一个类型
在跨平台的时候能更好的做到平台的兼容性
fun main() {
//A其实可以看做File的另一个别称
val file = A("path")
}
typealias A = File
19:DSL领域专用语言
外部DSL:JSON、XML、CSS、Makefile
内部DSL:Anko、build.gradle
- 优点:提升开发效率,减少沟通成本
- 特点:求专而不求全的一门语言