Kotlin的屬性委託:無上下文情況下Android的賦值(KAD 15),kotlinandroid

來源:互聯網
上載者:User

Kotlin的屬性委託:無上下文情況下Android的賦值(KAD 15),kotlinandroid

 

作者:Antonio Leiva

時間:Mar 9, 2017

原文連結:https://antonioleiva.com/property-delegation-kotlin/

 

 

如我們在前面文章中讀到的,屬性需要預設值,不能聲明屬性,而不給它們賦值。

 

 

由於你要儲存視圖到屬性中,這就產生一個問題了。在對象建立期間,這賦值代碼將被執行,而此時你不能訪問這個內容。

 

 

那你有能做什嗎?

 

 

屬性委託:委託屬性值到另一個對象

 

 

 

屬性委託將使用另一個對象,這個對象能夠調用get和set(如果使用了var)返回結果。

 

目前,我們還不能控制許多個物件的建立,如Android架構,在許多情況下,這委託將挽救我們的生命。

 

我將向你展示三個例子,我認為它們在Android中非常有用。

 

設定視圖到屬性

 

對於這個例子,我們用委託有兩個選項,且禁止用null(如果你能夠避免它,有些事情不建議使用)。

 

這是我最喜歡的,因為它迫使你對於不可變的、不太安全的屬性使用var。

 

用保留字lateinit,說明屬性不可為空,但是我們仍然沒有final價值:

1 lateinit var textView:TextView

 

在onCreate,我們能夠賦值給final值:

1 setContentView(R.layout.activity_main)2 textView = findView(R.id.welcomeMessage)3 toast(textView.text)

 

儘管它與委託notNull做相同的操作、被歸入第一喜歡,但這不是真正的委託。

 

第二個選擇則更加優雅。它由Lazy委託組成,直至屬性第一次被調用,相關代碼是不會執行:

1 val textView by lazy { findView(R.id.welcomeMessage) }

 

在textView的get被第一次調用之前,findView是不能啟動並執行。由於你不能錯誤的修改其值所以它更安全,並且它不會強制我們在setContentView之後記得設定它。

 

此刻,我們做:

 

1 toast(textView.text)

 

 

這行代碼將在lazy形式下被執行。

 

如你所見,委託的方式用by保留字表示。

 

我們來看另一個例子。

 

 通知適配器變更

 

在適配器中,我們有items屬性,每次自動啟動adapter時更新。

 

1 var items: List by Delegates.observable(emptyList()) {2     _, _, _ -> notifyDataSetChanged()3 }

 

它簡單地設定初始值,然後在每次更改後調用定義的函數。

 

 

在這種情況下,我只是調用notifyDataSetChanged,但是,如你所見,函數收到的新舊兩個值,所以在技術上你可以檢查變化是什麼,只更新其區別。

 

如果你對這個例子有興趣,我在另一篇文章更廣泛的描述它。

 

聲明Lazy方法的Dagger圖

 

 

 

 

這是我發現的非常有用的另一個情形。

 

 

返回到lazy,你能夠在屬性聲明期間,用它聲明應用的component:

 

1 val component: AppComponent by lazy { 2     DaggerAppComponent3             .builder()4             .appModule(AppModule(this))5             .build() 6 }

 

 

這個方法,你不需要用lateinit,屬性則為不可變的。

 

如果在Activity中,用subcomponents,你能夠做相同的事:

1 class HomeActivity : AppCompatActivity(), HomePresenter.View {2     val component by lazy { app.component.plus(HomeModule(this)) }3     ...4 }

 

新Kotlin 1.1版本:局部委託屬性

 

我們已經見到怎樣用委託是給我們類屬性的額外能力。而例如lazy,對變數也真的有協助嗎?Kotlin是缺乏這一特性的。

 

現在,用局部委託屬性,我們做:

 

 1 fun testLocalDelegation() { 2     val database by lazy { createDatabase() } 3     val cache by lazy { createMemoryCache() } 4  5     if (mustUseDatabase()) { 6         database.use { ... } 7     } else { 8         cache.use { ... } 9     }10 }

 

 

儘管不使用lazy委託,這個例子能夠解決,但它還是有助於理解這些概念。

 

我們有幾個可能會或不會被使用的“笨重”對象。通過用lazy,我們能夠延遲它們的執行個體化,直到我們確信要使用它們

 

 

在首次使用時,花括弧內的代碼被執行,且被緩衝起來,以備以後再使用。

 

 結論 

 

 

屬性委託將協助你屬性更強大,更簡化,且代碼可重用。

 

 

這裡我們僅僅看到Kotlin庫的標準屬性,而你能夠建立你自己的屬性。

 

例如在這本書中,我有實現從SharedPreference儲存和取回資料。

 

如果你要學習更多這些內容,足夠流暢建立自己的Android應用程式,我建議你擷取這本免費指南,學習怎樣建立你的第一個項目,或直接擷取這本書,學習怎樣從頭開始建立一個完整的應用程式。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.