kotlin-第四章(高级特性)

  • 解构
  • 循环和操作符
  • 运算符重载
  • 作用域函数
  • 中缀表达式
  • 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.png

image.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

  • 优点:提升开发效率,减少沟通成本
  • 特点:求专而不求全的一门语言

20:用kotlin构建DSL

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容