簡介
隨著kotlin在我的程式碼中佔比越來越大,我覺得自己有必要在一段時間的使用之後總結有哪些好的用法和哪些壞的用法。這篇文章記錄了個人習慣了的幾個kotlin寫法,如果覺得我的這幾種用法無論是效能上或是可讀性、可維護性上有問題,歡迎和我一起討論。
幾種習慣用法
-
一、使用?.let代替空判斷
private fun getInfo(jsonObject: JSONObject?): Info? { return jsonObject?.let { val uri = it.optString("uri") val length = it.optString("length") Info(uri, length) } } 複製程式碼
這樣寫和用if判空的寫法沒有區別,實際上根據這段程式碼編譯出的位元組碼反編譯得到的java程式碼就是if...else...形式的。這樣做的好處在於:
-
1.var可空屬性
當物件是var可空屬性時,即使在判斷非空的程式碼塊內也不能把物件當做非空物件,而必須加上!!,導致損失了kotlin提供的空安全。原因是kotlin考慮到多執行緒問題,即使在判斷非空的程式碼塊內var可空屬性仍可能被其他執行緒設定為null。而區域性變數和val可空屬性就不需要考慮多執行緒問題,可以再判斷非空的程式碼塊內可以把物件當做非空物件。 使用?.let可以解決這個問題,原因是let程式碼塊內部使用的it是接收物件的引數,是區域性變數。
-
2.多重判斷中的使用
// if...else...寫法 private fun testIfElse(): Object? { return if (a !== null) { val b = handleA(a) if (b !== null) { handleB(b) } else { null } } else { null } } // ?.let寫法 private fun testLet(): Object? { return a?.let { handleA(it) }?.let { handleB(it) } } 複製程式碼
-
-
二、使用apply做物件的初始化
return TextView(context).apply { text = "test" setOnClickListener(onClickListener) } 複製程式碼
-
三、使用let(apply、takeIf、run...)將整塊邏輯分割開來
File(url).takeIf { it.exists() } ?.let { JSONObject(NetworkUtils.postFile(SERVER_URL, url)) }?.takeIf { it.optString("message") == "success" } ?.let { post(it.optString("result")) } ?: mHandler.post { view?.onFail() } 複製程式碼
這段程式碼的功能是上傳檔案、獲得資料再上傳資料,使用let這種方法能將這幾個部分的邏輯完全分離。
總結
kotlin的語法其實都可以看做java的語法糖,相當於多一層封裝,多這一層封裝帶來效能損失和可讀性提高,如何合理使用kotlin的奇妙語法寫出讓人賞心悅目的程式碼而又不濫用,這是我以後kotlin開發過程中將持續探索的問題。