kotlin 函數和 Lambda 表達式

github地址

函數和 Lambda 表達式

  • Lambda 表達式
  • 內聯函數

    函數的中綴表示法

    中綴表示法
  • 首先說它的使用條件:
    • 他們是成員函數或擴展函數
    • 他們只有一個參數
    • 他們用 infix 關鍵字標註
  • 實際用法:咱們先看看幾個kotlin的源碼
/** Shifts this value left by [bits]. */
    public infix fun shl(bitCount: Int): Int
    /** Shifts this value right by [bits], filling the leftmost bits with copies of the sign bit. */
    public infix fun shr(bitCount: Int): Int
    /** Shifts this value right by [bits], filling the leftmost bits with zeros. */
    public infix fun ushr(bitCount: Int): Int


/**
 * Creates a tuple of type [Pair] from this and [that].
 *
 * This can be useful for creating [Map] literals with less noise, for example:
 * @sample samples.collections.Maps.Instantiation.mapFromPairs
 */
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)


/**
 * Returns a set containing all elements that are contained by both this set and the specified collection.
 * 
 * The returned set preserves the element iteration order of the original collection.
 */
public infix fun <T> Iterable<T>.intersect(other: Iterable<T>): Set<T> {
    val set = this.toMutableSet()
    set.retainAll(other)
    return set
}


/**
 * Returns a progression from this value down to the specified [to] value with the step -1.
 * 
 * The [to] value has to be less than this value.
 */
public infix fun Short.downTo(to: Short): IntProgression {
    return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1)
}

`複製代碼

從源碼中能夠看出 infix 的用法:當咱們定義一個類的函數或者擴展函數的時候,若是這個函數接受的參數和本身是同一類的,而且又反回值那麼就採用中綴表示法html

高階函數與 lambda 表達式

lambda 表達式java

  • 這節內容有的人可能有的學習起來會以爲有點難,其實只要轉變一下觀點記住下面的幾點,就很簡單了。看完後就能夠愉快的看kotlin源碼學習了。
  • 一個 lambda 表達式或匿名函數是一個「函數字面值(字面函數)」,即一個未聲明的函數,作爲表達式傳遞。
  • 函數類型:() -> T
  • kotlin 源碼大量採用了lambda表達式,這樣說明之後本身在寫代碼的時候,必然也會用到不少,這個也很簡單,咱們記住這點:將函數用做爲參數或返回值的函數是 高階函數,kotlin通常採用函數字面值(字面函數)的方式往高階函數傳參,一個高階函數接受另外一個lambda 表達式做爲最後一個參數,lambda 表達式參數能夠在
    圓括號參數列表以外傳遞。
  • kotlin的lambda 表達式和高階函數能夠爲咱們省去之前不少的java接口。下面的接口省掉了OnClickListenter這個接口
//簡單改造view的setOnClickListenter
class Main2Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        var view = View()
        view.setOnClickListenter { 
            it->it.toHome()
        }
    }
}
class View{
    fun toHome() {

    }
    fun setOnClickListenter(listerner: (v:View) -> Unit) {
        listerner(this);
    }
}複製代碼
  • 接受者 是接受這個函數的對象,也就是調用這個函數的對象
  • 帶接收者的函數字面值:能夠調用該接收者對象上的方法而無需任何額外的限定符。這相似於擴展函數,它允你在函數體內訪問接收者對象的成員。
    能夠這樣理解,當咱們在寫一個高階函數的時候,發覺須要用到lambda 表達式中參數對象裏面的方法的時候,這個時候就用到帶接收者的函數字面值。kotlin源碼裏 面不少這樣的函數,下面舉例說明:
/**
 * 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()

/**
 * 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 }

/**
 * 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 }複製代碼

然而這裏幾個函數在咱們項目中會常常用到,好比這樣:如今有一本書,我要更具他如今的價格來分類,分完之,還要的獲得這麼書的名字git

class Main2Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        var book = Book()
        var name = book.apply {
            var price = getPrice()
            if (price < 50) {
                Toast.makeText(this@Main2Activity,"小於50", Toast.LENGTH_LONG).show()//this@Main2Activity 是this表達式
                type = "便宜書"
            }else{
                Toast.makeText(this@Main2Activity,"大於50", Toast.LENGTH_LONG).show()
                type = "貴書"
            }
        }.getName()
    }
}
class Book{
    var type:String? = null
    fun getName():String {
        return "youxin"
    }
    fun getPrice():Int {
        return 100
    }
}複製代碼
  • 接受者 是接受這個函數的對象,也就是調用這個函數的對象
  • this表達式
相關文章
相關標籤/搜索