kotlin进阶篇(一)

  • 转载时请注明出处,谢谢
  • / 0评 / 0

      相信我们经过基础篇的学习应该对Kotlin有了初步的认识,本篇将进一步讲解Kotlin语法知识,并学习一些开发中的使用技巧。

    安全调用运算符: "?."

    "?."将一次null检查和一次方法调用合成一个操作,例如: view?.renderNickname(),如果不使用该操作符将等同于: if(view != null) view.renderNickname() , 如你所见 "?.” 操作符使代码看起来更为简洁。

    Elvis运算符: “?:”

    该运算符亦被称作null合并运算符,它提供代替null的默认值。例如:val str = tempStr ?: "abc" ,elvis操作符接受两个运算数,如果第一个运算数不为null,运算结果就为第一个运算数;如果第一个运算数为null,运算结果则为第二个操作符。

    非空断言: "!!"

    非空断言可将任何值转换成非空类型。如果对null值做非空断言则会抛出空指针异常。开发中如果不确定某个变量的取值情况下尽量不要使用非空断言。非空断言的使用方式:view!!.renderFeed(feeds)

    as操作符

    该操作符可为import提供重命名操作, 例如: import com.squareup.leakcanary.LeakCanary as LC , 然后通过临时名称使用该导入模块,例如:LC.install(this) 。as操作符亦可作为类型转换工具使用,例如:val activity = context as Activity

    let函数

    函数定义:

    fun <T, R> T.let(f: (T) -> R): R = f(this)
    

    和安全调用运算符一起使用,它允许对表达式求值,检查求值结果是否为null,默认当前对象作为闭包的it参数,返回值是函数里面的最后一行。例如:

    fun testLet() {
     view?.let {
                it.showRefreshCompleted()
                 it.renderFeeds(feeds) 
    }
    

    with函数

    函数定义:

    fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
    

    该函数把它的第一个参数转换成作为第二个参数传给他的lambda的接受者,可以显示的通过this访问这个接收者。例如:

    fun testWith() {
        with(ArrayList<String>()) {
            add("testWith")
            add("testWith")
            add("testWith")
            println("this = " + this)
        }
    }
    

    apply函数

    函数定义:

    fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
    

    apply函数几乎和with函数一模一样,唯一的区别就是apply始终会返回作为实参传递给它的对象。例如:

    fun testApply() {
        ArrayList<String>().apply {
            add("testApply")
            add("testApply")
            add("testApply")
        }.let { println(it) }
    }
    

    run函数

    函数定义:

    fun <T, R> T.run(f: T.() -> R): R = f()
    

    在run中,用this代表当前引用对象,并且调用其方法时,this可省略。
    返回值是语句块的最后一行,若最后一行语句无返回值,则整个run语句块也无返回值。

    fun testRun() {
        val list: MutableList<String> = mutableListOf("A", "B", "C")
        val change: Any
        change = list.run {
            add("D")
            add("E")
            this.add("F")
            size
        }
        println("list = $list")
        println("change = $change")
    }
    

    输出:

    list = [A, B, C, D, E, F]
    change = 6
    

    高阶函数

    高阶函数可以将一个函数作为参数或者返回值,方法形参传入加上"::"操作符。例如:

     fun add(x: Int = 0, y: Int = 0): Int {
        return x + y
     }
    
     fun operate(x: Int = 0, y: Int = 0, func: (Int, Int) -> Int) {
        print(func(x, y))
     }
    
     fun getValue() {
        operate(1, 2, ::add)
     }
    

    Lambda表达式

    Lambda 表达式的完整语法形式,即函数类型的字面值如下:

    val sum = { x: Int, y: Int -> x + y }
    

    lambda 表达式总是被大括号括着, 完整语法形式的参数声明放在括号内,并有可选的类型标注, 函数体跟在一个 -> 符号之后。如果推断出的该 lambda 的返回类型不是 Unit类型,则 lambda 主体中的最后一个表达式将会视为返回值。其次,当函数参数是函数的最后一个参数并且传入一个lambda表达式作为相应的参数时,可以在括号外指定它,例如:

    fun getValue1() {
        operate(1, 2,{
            x, y -> x + y
        }) 
    }
    
    fun getValue2() {
        operate(1, 2) {
            x, y -> x + y
        }
    }
    

    如果lambda表达式只有一个参数,kotlin可以推算出签名,则我们可以不用声明唯一的参数,它将为我们隐式声明为名为it,例如:

    button.setOnClickListener { it.isEnabled = false }
    

    如果lambda表达式是调用的唯一参数,则调用中的圆括号可以完全省略:

    fun String.upper(body: (String) -> String): String {
        return body(this)
    }
    
    fun transform() {
        "Kotlin".upper { it.toUpperCase() }
    }
    

    匿名函数

    匿名函数与常规函数一样,只是省略了函数名称而已:

    fun String.upper(body: (String) -> String): String {
        return body(this)
    }
    
    fun transform() {
        "Kotlin".upper(fun(str: String): String {
            return str.toUpperCase()
        })
    }
    

    Lambda表达式和匿名函数之间的另一个区别是非局部返回的行为。具体指一个不带标签的 return 语句总是在用 fun 关键字声明的函数中返回。 lambda 表达式中的 return 将从包含它的函数返回,而匿名函数中的 return 将从匿名函数自身返回。

    fun foo() {
        numbers.forEach {
            if (it == 0) return
            print(it)
        }
    }
    

    值得注意的是:这种非局部的返回只支持传给内联函数的 lambda 表达式。 如果我们需要从 lambda 表达式中返回,我们必须给它加标签并用以限制 return。

    fun transform(): String {
        "Kotlin".upper {
            print(it.toUpperCase())
            return@upper it.toUpperCase()
        }
        "Kotlin".upper(fun(str:String): String {
            return str.toUpperCase()
        })
    }
    

      本篇介绍了Kotlin语言中的操作符、转换函数、lambda等,下篇将重点讲解下Kotlin语言级委托机制。

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注