Kotlin学习笔记(二)

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  run(block: () -> R): R = block()

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

kotlin.run { findViewById(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.run(block: T.() -> R): R = block()

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

findViewById(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  with(receiver: T, block: T.() -> R): R = receiver.block()

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

with(findViewById(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.apply(block: T.() -> Unit): T { block(); return this }

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

//f返回值为TextView
findViewById(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.also(block: (T) -> Unit): T { block(this); return this }

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

//返回值为TextView
 findViewById(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.let(block: (T) -> R): R = block(this)

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

findViewById(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.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null

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

findViewById(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.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null

和 takeIf相反。

你可能感兴趣的:(Kotlin学习笔记(二))