iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 12
2
Software Development

Kotlin for Android系列 第 12

Day 12. Kotlin 2D2E

線上 Kotlin 練習編譯器:
https://play.kotlinlang.org/ (Dark)
https://try.kotlinlang.org/ (Light)
今日的練習環境改用上方提供的 Dark 來展示

  2D2E 並不是什麼專有名詞,只是在 Kotlin 介紹的尾聲,作者挑了四個好玩的項目要來介紹:

  • Data Classes
  • Destructuring Declarations
  • Exceptions
  • Extensions

Data Classes

 我們時常會宣告 class 用來進行資料的儲存與處理,因此可以透過 data 關鍵字套用在 class 之前,讓你可以使用一些標準且有效益的方法:

  • toString()
  • equals() / hashCode()
  • componentN() 方法
  • copy()

  要使用 data class 有三點需要注意:

  1. 必須擁有至少一個主建構子參數
  2. 所有的主建構子參數都要標記為 valvar
  3. 此類別不可以為 abstractopensealedinner

toString()

  第一個先介紹 toString() 的用途,可以列出目前物件各屬性值的狀態,參考下圖的示範,可以發現透過 data class 提供的方法,可以很明瞭的看出物件內容,而一般物件則不然。

https://ithelp.ithome.com.tw/upload/images/20181026/20111944LW4cC7zUro.png


equals()

  接著是 equals 的差異,在資料物件中,只要內容的值相同就視為一樣,而一般物件則不相同。

https://ithelp.ithome.com.tw/upload/images/20181026/20111944CC9UrzWkWB.png

hashCode()

  從 hashCode() 來看也是相同結果:

https://ithelp.ithome.com.tw/upload/images/20181026/201119442pfbaoKHsN.png


componentN()

  還有自動生成的 component 方法,順序是依照主建構子的宣告排序:

https://ithelp.ithome.com.tw/upload/images/20181026/20111944SuaH79xv4O.png


copy()

  最後說明的是 copy,要複製物件並不像是數值屬性用 = 就可以完成,必須使用 copy 進行完整複製,否則會像 clone2 一樣指向同一個物件,參考下圖就能明瞭 isDataclone1clone2 之間的關係,copy() 可以直接使用也可以傳入主建構子參數,如圖中的 copy(“isB”) 更新複製出來的內容。

https://ithelp.ithome.com.tw/upload/images/20181026/20111944Rb27LTtXLu.png

  Data class 的應用可以再往下鑽研更深的主題,但在本系列文章就僅簡略介紹概念的部分,有興趣的讀者可以至下方參考資料連結詳讀,接著介紹 Destructuring Declarations 解構宣告。


Destructuring Declarations

  解構宣告也滿有趣,先圖解第一種應用如下圖,可以將物件的屬性值解構成參數表示,須注意的是 var (x1, x2) 括號內的名稱是自訂的,跟類別的屬性名稱沒有關連性,是按照順序將值解構,所以就算你使用 var (age)age 這個變數依然會是 Person 類別中的 name,各位可以試試看。

https://ithelp.ithome.com.tw/upload/images/20181026/20111944IGRv2LsYSY.png

  原理其實是在編譯後會自動變成 data class 中提過的 componentX(),如上圖的註解區域,所以剛剛提到的按照順序解構,原因就是此機制的結果。

  如果只想取得部分的值,可以使用 _ 底線符號將該不需要的部分略過,如下圖的展示:

https://ithelp.ithome.com.tw/upload/images/20181026/20111944JDq5TRR4CQ.png

  解構還能運用在函式的複數回傳值,比起接收整個回傳物件,可以直接利用解構宣告進行更直覺的設計:

https://ithelp.ithome.com.tw/upload/images/20181026/20111944EE9Zb98uJe.png


  在迴圈、Lambda 章節有出現過的用法,其實機制也是相同:

https://ithelp.ithome.com.tw/upload/images/20181026/20111944hfDiHzHtUL.png


Exceptions

  接著介紹 2E 的部分,下圖展示 Exceptions 在 Kotlin 的用法,與一般程式相同,可用參數 e 接收 Exception 型態的資料,若程式中產生例外事件沒有接收,就會一直往上層拋,直到應用程式崩潰為止。

  在 Kotlin 內有個型態 Nothing 可以用來代表無所事事,可以用來強調這段函式不回傳值。

https://ithelp.ithome.com.tw/upload/images/20181026/20111944BTublEEMvJ.png


  Try-catch 的另一種用法可以配合轉型使用,程式設計時如果有無法保證的地方,記得運用例外事件,下列這段程式碼主要進行將參數轉型成數值 Int,但你無法預期輸入值一定會是整數型態,有時候甚至會遇到文字,因此例外狀況的處理非常重要。

    val a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }

Extensions

  另一個 E 是擴充方法 (Extensions),有時候你會想要在某個形態上延伸一個自定義的方法,比起寫一個普通的 fun 傳入/傳出,是另一個更好的選擇,透過擴充的方式,以型態為基底在上面延伸擴充自己的方法,最大的好處是,相同型態的變數在使用時,IDE 的程式碼建議視窗中也會出現,比起一般方法在使用上更直覺。

  下圖展示了以 String 型態以及 List 型態擴充的兩個方法,clearDash() 用途在字串變數使用時,能夠清除所有 - 符號;swap() 用途是將 List 的指定兩個索引調換順序。當在程式設計生涯,除了使用原始提供的方法外,你有可能會發展出一套屬於自己慣用或符合特定產業需求的擴充函式庫,這個程式庫的價值非常重要,對於程式開發效率有正面影響。

https://ithelp.ithome.com.tw/upload/images/20181026/20111944Eo5QxLICWj.png


  今天的學習就到這邊,同時也宣告純程式碼教學的內容到此告一個段落,這個教學的目的是引起各位的興趣及簡單的概念學習,各程式語言都有進階深入的使用方法,但在 30 天課程中是沒辦法完整呈現的,因作者的主題是 Kotlin for Android 因此比例規劃各占一半,有興趣繼續鑽研的可以查詢 Advanced Kotlin 等關鍵字,接著的課程會回到 Andriod Studio 上,我們明天見!


資料參考

Data Classes
https://kotlinlang.org/docs/reference/data-classes.html

Kotlin 的 data class 會對你的程式產生什麼樣的化學反應
https://ingramchen.io/blog/2017/06/kotlin-data-class.html

Kotlin 的 data class 會對你的程式產生什麼樣的化學反應
https://ingramchen.io/blog/2017/06/kotlin-data-class.html

Destructuring Declarations in Kotlin
https://www.baeldung.com/kotlin-destructuring-declarations

Destructuring Declarations
https://kotlinlang.org/docs/reference/multi-declarations.html

Exceptions
https://kotlinlang.org/docs/reference/exceptions.html

Extensions
https://kotlinlang.org/docs/reference/extensions.html


上一篇
Day 11. Kotlin Lambda
下一篇
Day 13. Android Studio x 版本控制 & Git - 1/2
系列文
Kotlin for Android30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言