美文网首页
Kotlin学习笔记(二)

Kotlin学习笔记(二)

作者: 武穆遗书 | 来源:发表于2017-11-03 14:17 被阅读0次

    1. 构造函数

    在 Kotlin 中的⼀个类可以有⼀个主构造函数和⼀个或多个次构造函数。主构造函数是类头的⼀部分:它跟在类名后。

    class Person constructor(firstName: String) {
    }
    

    如果主构造函数没有任何注解或者可⻅性修饰符,可以省略这个 constructor 关键字。

    class Person(firstName: String) {
    }
    

    主构造函数不能包含任何的代码,初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中:

    class Customer(name: String) {
        init {
            logger.info("Customer initialized with value ${name}")
        }
    }
    

    注意,主构造的参数可以在初始化块中使⽤。它们也可以在类体内声明的属性初始化器中使⽤:

    class Customer(name: String) {
        val customerKey = name.toUpperCase()
    }
    

    与普通属性⼀样,主构造函数中声明的属性可以是可变的(var)或只读的(val)。
    如果构造函数有注解或可⻅性修饰符,这个 constructor 关键字是必须的,并且这些修饰符在它前⾯:

    class Customer public @Inject constructor(name: String) { …… }
    

    类也可以声明前缀有 constructor的次构造函数:

    class Person {
        constructor(parent: Person) {
            parent.children.add(this)
        }
    }
    

    如果类有⼀个主构造函数,每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托。委托到同⼀个类的另⼀个构造函数⽤ this 关键字即可:

    class Person(val name: String) {
        constructor(name: String, parent: Person) : this(name) {
            parent.children.add(this)
        }
    }
    

    如果⼀个⾮抽象类没有声明任何(主或次)构造函数,它会有⼀个⽣成的不带参数的主构造函数。构造函数的可⻅性是 public。如果你不希望你的类有⼀个公有构造函数,你需要声明⼀个带有⾮默认可⻅性的空的主构造函数:

    class DontCreateMe private constructor () {
    }
    

    2. run、with、apply、also、let、takeIf、takeUnless

    标题上的函数都位于 Standard.kt文件下,下面我们一个个过一遍:

    • run
    /**
     * Calls the specified function [block] and returns its result.
     */
    @kotlin.internal.InlineOnly
    public inline fun <R> run(block: () -> R): R = block()
    

    在kotlin中,将函数⽤作参数或返回值的函数叫高阶函数。这里把block()作为参数,其返回值和run方法的返回值相同,为R。举个栗子:

    kotlin.run { findViewById<TextView>(R.id.text_view) }.text = "kotlin"
    
    /**
     * Calls the specified function [block] with `this` value as its receiver and returns its result.
     */
    @kotlin.internal.InlineOnly
    public inline fun <T, R> T.run(block: T.() -> R): R = block()
    

    这个run方法为T类的扩展方法(关于扩展方法不懂的自行百度),方法的返回值是block()的返回值,这里注意block()也是T类的扩展方法。
    举个栗子,run:

    findViewById<TextView>(R.id.text_view).run {
        text = "kotlin" //设置textview内容,返回值为Unit
    }
    
    • with
    /**
     * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
     */
    @kotlin.internal.InlineOnly
    public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
    

    with不是扩展方法,它的第一个参数是一个T类型的接收者,第二个参数为T的扩展方法block(),返回值为block()的返回值。看栗子:

    with(findViewById<TextView>(R.id.text_view)){
        text = "kotlin"
    }
    
    • apply
    /**
     * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
     */
    @kotlin.internal.InlineOnly
    public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
    

    apply函数返回值为它本身,参数为T的扩展方法,看栗子:

    //f返回值为TextView
    findViewById<TextView>(R.id.text_view).apply {
         text = "kotlin" //设置textview内容
    }.setOnClickListener { ... }
    
    • also
    /**
     * Calls the specified function [block] with `this` value as its argument and returns `this` value.
     */
    @kotlin.internal.InlineOnly
    @SinceKotlin("1.1")
    public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
    

    also函数是T类的扩展方法,返回值类型为T,参数为block(T)函数,block(T)函数的参数为T,无返回值:

    //返回值为TextView
     findViewById<TextView>(R.id.text_view).also {
          it.text = "kotlin" //设置textview内容
     }.setOnClickListener { ... }
    
    • let
    /**
     * Calls the specified function [block] with `this` value as its argument and returns its result.
     */
    @kotlin.internal.InlineOnly
    public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
    

    let函数是T类的扩展方法,返回值类型为block方法的返回值类型,block方法的参数为T:

    findViewById<TextView>(R.id.text_view).let { 
        it.text = "kotlin"
    }//返回值类型为setText的返回值类型
    
    • takeIf
    /**
     * Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
     */
    @kotlin.internal.InlineOnly
    @SinceKotlin("1.1")
    public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
    

    takeIf函数为T类扩展方法,参数为predicate()方法,这个方法的参数为T,返回值为Boolean,如果为true返回T,否则返回null:

    findViewById<TextView>(R.id.text_view).takeIf {
        it.text.isEmpty()
    }?.text = "kotlin"//如果TextView的text不为空就会返回null,需要空安全
    
    • takeUnless
    /**
     * Returns `this` value if it _does not_ satisfy the given [predicate] or `null`, if it does.
     */
    @kotlin.internal.InlineOnly
    @SinceKotlin("1.1")
    public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
    

    和 takeIf相反。

    相关文章

      网友评论

          本文标题:Kotlin学习笔记(二)

          本文链接:https://www.haomeiwen.com/subject/usizpxtx.html