Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Kotlin中的“忍者”函數 —— 理解泛型的能力(KAD 12),kotlinkad

Kotlin中的“忍者”函數 —— 理解泛型的能力(KAD 12),kotlinkad

編輯:關於android開發

Kotlin中的“忍者”函數 —— 理解泛型的能力(KAD 12),kotlinkad


作者:Antonio Leiva

時間:Feb 8, 2017

原文鏈接:https://antonioleiva.com/generic-functions-kotlin/

 

 

Kotlin的一些特性組合起來與泛型混合使用創建函數可以極大的簡化你的編碼,且保證它的可讀性。

 

在Kotlin庫中,有幾個函數非常實用,一旦你掌握它們的概念使用起來就非常容易。

 

with函數

 

盡管Kotlin標准庫中有幾個相似的函數,但是,我計劃聚焦在with的各個部分上。

 

這個函數允許做什麼?用了它,我們可以用一變量的代碼塊作為其上下文,這樣就不需要每次使用它重復它的名字。

 

它們可以替代構建器,不需要為每個類創建特定構建器。

 

例如,回到前面文章的ViewGroup例子,可以轉換這行代碼:

1 val childViews = (0..viewGroup.childCount - 1).map { viewGroup.getChildAt(it) }

 

到:

1 with(viewGroup) {
2     val childViews = (0..childCount - 1).map { getChildAt(it) }
3 }

 

如你所見,括號內代碼的行為就像是其在本類中。

 

那我們如何得到這樣呢?我們在之前的擴展函數中已經見過了。

 

擴展函數作為其他函數的自變量

 

這事情越來越復雜了,但是這是非常有用的,你需要理解它。

 

你能夠定義擴展函數為另一個函數的參數。

 

你怎樣實現with函數執行前面的例子?最簡單就是這樣:

1 inline fun with(view: ViewGroup, f: ViewGroup.() -> Unit) {
2     view.f()
3 }

 

上面代碼以參數形式接收ViewGroup,且一個用於ViewGroup的擴展函數。ViewGroup可無障礙執行那個函數。

 

但是,這限制較多。對數據的每種類型我們需要一個類似的函數?

 

當然不是。

 

泛型類型

 

我們能夠十分容易地用泛型轉換上面的函數。只需用T替換ViewGroup:

1 inline fun with(obj: T, f: T.() -> Unit) {
2     obj.f()
3 }

 

現在它就可以用於任何類型。例如:

1 with(textView) {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5 }

 

但是,在我們開始討論時,我們忽略一項重要的能力:構建器的角色。

 

泛型類型的返回值

 

如果我們想要一個真正的構建器,我們就需要以某種方式返回構建值:

1 inline fun with(obj: T, f: T.() -> Unit): T {
2     obj.f()
3     return obj
4 }

 

那樣,我們的代碼應該是這樣:

1 val textView = with(TextView(this)) {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5 }

 

注:sp() 是Anko庫的函數,在這系列文章前面談論過它。

 

如果你看函數的正式定義,它非常類似我們已經做的:

1 public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

 

這裡主要的區別在於擴展函數返回的值可能會不同傳遞參數。

 

為了獲得與使用常規函數的相同結果,我們需要這樣做:

1 val textView = with(TextView(this)) {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5     this
6 }

 

最後一行意思是將返回執行擴展函數的對象。

 

其他有趣的函數

 

有一個函數功能非常類似我們在前一節得到的,它叫apply。

 

apply

 

這個函數作為對象的擴展函數,而不是對象的參數:

1 val textView = TextView(this).apply {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5 }

 

let

 

如果相應的對象不是null,它將只需內部函數的代碼:

1 textView?.text?.let { toast(it) }

 

僅當TextView和text都不為null,text將被顯示在消息框(toast)中。

 

結論

 

結合擴展函數,利用泛型類型的能力,我們能做一些非常有趣的事情。

 

我鼓勵你創建自己的函數以簡化你的日常工作。

 

http://www.bkjia.com/Androidjc/1192072.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/1192072.htmlTechArticleKotlin中的“忍者”函數 —— 理解泛型的能力(KAD 12),kotlinkad 作者: Antonio Leiva 時間: Feb 8, 2017 原文鏈接: https://antonioleiva.com/generic-f...

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved