日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
6個(gè)能讓你的Kotlin代碼庫(kù)更有意思的“魔法糖”

語法糖會(huì)導(dǎo)致分號(hào)的悲劇。—— Alan J. Perlis

成都創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),姚安網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:姚安等地區(qū)。姚安做網(wǎng)站價(jià)格咨詢:18982081108

我們不斷地失去一些東西。其中一些東西相對(duì)來說會(huì)更重要,現(xiàn)在重新揀起來還不算太晚。Kotlin 語言為程序員的生活帶來了大量新的概念和特性,它們?cè)谌粘i_發(fā)中使用起來會(huì)很困難。我在生產(chǎn)環(huán)境中使用了兩年 Kotlin 之后,才感受到它帶來的快樂和滿足。這是怎么發(fā)生的?原因就在那些小小的語法糖中。

我會(huì)在本文中與你分析我最喜歡的 Kotlin 語法糖,它們是在我需要寫簡(jiǎn)潔而魯棒 Android 應(yīng)用程序組件時(shí)發(fā)現(xiàn)的。為了讓這篇文章讀起來更輕松,我把它分成三個(gè)部分。在這第一部分中,你會(huì)看到密封類和 when() 控制流函數(shù)。愉快的開始吧!

擁抱“模式匹配”的密封類

最近我的工作中有機(jī)會(huì)使用 Swift。我不僅要審核代碼,還要將其中一些組件翻譯成 Kotlin 實(shí)現(xiàn)。我讀的代碼越多,就越感到驚訝。最對(duì)我來說,最吸引人的特性是枚舉。可惜 Kotlin 的枚舉并不太靈活,我不得不挖掘合適的替代品: 密封類 。

密封類在編程界并不是什么新鮮玩意兒。事實(shí)上,密封類是一個(gè)非常知名的語言概念。Kotlin 引入了 sealed 關(guān)鍵字,它可用于類聲明,表示對(duì)類層次結(jié)構(gòu)的限制。某個(gè)值可以是有限類型中的一個(gè),但它不能是其它類型。簡(jiǎn)單地說,你可以使用密封類來代替枚舉,甚至做更多事情。

來看看下面的示例代碼。

 
 
 
 
  1. sealed class Response  
  2. data class Success(val body: String): Response()  
  3. data class Error(val code: Int, val message: String): Response()  
  4. object Timeout: Response() 

乍一看,這些代碼除只是聲明了一些簡(jiǎn)單的繼承關(guān)系,但步步深入,就會(huì)提示一個(gè)諒人的真相。為 Response 類添加的 sealed 關(guān)鍵字到底起到了什么作用呢?提示這個(gè)問題最好的方法是使用 IntelliJ IDEA Kotlin Bytecode 工具。

第一 步。查看 Kotlin 字節(jié)碼 (Kotlin Bytecode)

第二步。將 Kotlin 字節(jié)碼反編譯成 Java 代碼

經(jīng)過這樣非常簡(jiǎn)單地翻譯,你可以看到 Kotlin 代碼對(duì)應(yīng)的 Java 代碼呈現(xiàn)。

 
 
 
 
  1. public abstract class Response { 
  2.    private Response() { 
  3.    } 
  4.  
  5.    // $FF: synthetic method 
  6.    public Response(DefaultConstructorMarker $constructor_marker) { 
  7.       this(); 
  8.    } 

你可能已經(jīng)猜到了,密封類專們用于繼承,所以它們是抽象的。不過他們變得與枚舉相似的?在這里,Kotlin 編譯器做了大量的工作,讓你可以在 when() 函數(shù)中將 Response 的子類用作分支。此外,Kotlin 提供了很大的靈活性來允許對(duì)密封類的繼承結(jié)構(gòu)可以被當(dāng)作數(shù)據(jù)聲明甚至對(duì)象來使用。

 
 
 
 
  1. fun sugar(response: Response) = when (response) { 
  2.     is Success -> ... 
  3.     is Error -> ... 
  4.     Timeout -> ... 

它不僅提供了非常徹底的表達(dá)式,還提供了自動(dòng)類型轉(zhuǎn)換,因此你可以在不需要額外的轉(zhuǎn)換的情況下使用 Response 實(shí)例。

 
 
 
 
  1. fun sugar(response: Response) = when (response) { 
  2.     is Success -> println(response.body) 
  3.     is Error -> println("${response.code} ${response.message}") 
  4.     Timeout -> println(response.javaClass.simpleName) 

你能想象一下,如果沒有一個(gè) sealed 的功能,或者根本沒有 Kotlin ,它可能看起來是那么的丑陋和復(fù)雜?如果你忘記了 Java 語言的一些特性,請(qǐng)?jiān)俅问褂?IntelliJ IDEA Kotlin Bytecode ,但要坐下來使用 - 這可能會(huì)讓你暈倒。

 
 
 
 
  1. public final void sugar(@NotNull Response response) { 
  2.    Intrinsics.checkParameterIsNotNull(response, "response"); 
  3.    
  4.    String var3; 
  5.    if (response instanceof Success) { 
  6.       var3 = ((Success)response).getBody(); 
  7.       System.out.println(var3); 
  8.    } else if (response instanceof Error) { 
  9.       var3 = "" + ((Error)response).getCode() + ' ' + ((Error)response).getMessage(); 
  10.       System.out.println(var3); 
  11.    } else { 
  12.       if (!Intrinsics.areEqual(response, Timeout.INSTANCE)) { 
  13.          throw new NoWhenBranchMatchedException(); 
  14.       } 
  15.  
  16.       var3 = response.getClass().getSimpleName(); 
  17.       System.out.println(var3); 
  18.    } 

總結(jié)一下,我很高興在這種情況下使用 sealed 關(guān)鍵字,因?yàn)樗屛乙灶愃朴?Swift 的方式塑造我的 Kotlin 代碼。

使用 when()函數(shù)來排列

由于你已經(jīng)看到了 when()在 sealed 類中的用法,我決定再分享更多強(qiáng)大的功能。 想象一下,你必須實(shí)現(xiàn)一個(gè)接受兩個(gè) enums 并產(chǎn)生一個(gè)不可變狀態(tài)的函數(shù)。

 
 
 
 
  1. enum class Employee { 
  2.     DEV_LEAD, 
  3.     SENIOR_ENGINEER, 
  4.     REGULAR_ENGINEER, 
  5.     JUNIOR_ENGINEER 
  6.  
  7. enum class Contract { 
  8.     PROBATION, 
  9.     PERMANENT, 
  10.     CONTRACTOR, 

enum class Employee 描述了在公司 XYZ 中可以找到的所有角色, enum class Contract 包含所有類型的雇傭合同。 基于這兩個(gè) enums ,你應(yīng)該返回一個(gè)正確的 SafariBookAccess 。 而且,你的函數(shù)必須產(chǎn)生給定 enum 的所有排列的狀態(tài)。 第一步,我們來創(chuàng)建狀態(tài)生成函數(shù)的簽名。

 
 
 
 
  1. fun access(employee: Employee, 
  2.            contract: Contract): SafariBookAccess 

現(xiàn)在是時(shí)候定義 SafariBooksAccess 結(jié)構(gòu)體了,因?yàn)槟阋蚜私?sealed 關(guān)鍵字,這是使用它最適合的時(shí)機(jī)。封裝 SafariBookAccess 并不是必須的,但它是封裝不同情景下的 SafariBookAccess 的不同狀態(tài)的好方式。

 
 
 
 
  1. sealed class SafariBookAccess  
  2. data class Granted(val expirationDate: DateTime) : SafariBookAccess()  
  3. data class NotGranted(val error: AssertionError) : SafariBookAccess()  
  4. data class Blocked(val message: String) : SafariBookAccess() 

那么隱藏在 access() 函數(shù)后面的主要意圖是什么?全排列!讓我們羅列下。

 
 
 
 
  1. fun access(employee: Employee, 
  2.            contract: Contract): SafariBookAccess { 
  3.     return when (employee) { 
  4.         SENIOR_ENGINEER -> when (contract) { 
  5.             PROBATION -> NotGranted(AssertionError("Access not allowed on probation contract.")) 
  6.             PERMANENT -> Granted(DateTime()) 
  7.             CONTRACTOR -> Granted(DateTime()) 
  8.         } 
  9.         REGULAR_ENGINEER -> when (contract) { 
  10.             PROBATION -> NotGranted(AssertionError("Access not allowed on probation contract.")) 
  11.             PERMANENT -> Granted(DateTime()) 
  12.             CONTRACTOR -> Blocked("Access blocked for $contract.") 
  13.         } 
  14.         JUNIOR_ENGINEER -> when (contract) { 
  15.             PROBATION -> NotGranted(AssertionError("Access not allowed on probation contract.")) 
  16.             PERMANENT -> Blocked("Access blocked for $contract.") 
  17.             CONTRACTOR -> Blocked("Access blocked for $contract.") 
  18.         } 
  19.         else -> throw AssertionError() 
  20.     } 

這個(gè)代碼很完美,但你能讓它更像 Kotlin 嗎?當(dāng)你每天對(duì)同事的 PR/MR 進(jìn)行審查時(shí)會(huì)有什么建議嗎?你可能會(huì)寫一些這樣的評(píng)論:

  • 太多 when() 函數(shù)。使用 Pair 來避免嵌套。
  • 改變枚舉參數(shù)的順序,定義 Pair() 對(duì)象來讓它更易讀。
  • 合并重復(fù)的 return。
  • 改為一個(gè)表達(dá)式函數(shù)。

 
 
 
 
  1. fun access(contract: Contract, 
  2.            employee: Employee) = when (Pair(contract, employee)) { 
  3.     Pair(PROBATION, SENIOR_ENGINEER), 
  4.     Pair(PROBATION, REGULAR_ENGINEER), 
  5.     Pair(PROBATION, JUNIOR_ENGINEER) -> NotGranted(AssertionError("Access not allowed on probation contract.")) 
  6.     Pair(PERMANENT, SENIOR_ENGINEER), 
  7.     Pair(PERMANENT, REGULAR_ENGINEER), 
  8.     Pair(PERMANENT, JUNIOR_ENGINEER), 
  9.     Pair(CONTRACTOR, SENIOR_ENGINEER) -> Granted(DateTime(1)) 
  10.     Pair(CONTRACTOR, REGULAR_ENGINEER), 
  11.     Pair(CONTRACTOR, JUNIOR_ENGINEER) -> Blocked("Access for junior contractors is blocked.") 
  12.     else -> throw AssertionError("Unsupported case of $employee and $contract") 

現(xiàn)在它看起來更整潔,但 Kotlin 還有語法糖可以完全省略對(duì) Pair 的定義。棒!

 
 
 
 
  1. fun access(contract: Contract, 
  2.            employee: Employee) = when (contract to employee) { 
  3.     PROBATION to SENIOR_ENGINEER, 
  4.     PROBATION to REGULAR_ENGINEER -> NotGranted(AssertionError("Access not allowed on probation contract.")) 
  5.     PERMANENT to SENIOR_ENGINEER, 
  6.     PERMANENT to REGULAR_ENGINEER, 
  7.     PERMANENT to JUNIOR_ENGINEER, 
  8.     CONTRACTOR to SENIOR_ENGINEER -> Granted(DateTime(1)) 
  9.     CONTRACTOR to REGULAR_ENGINEER, 
  10.     PROBATION to JUNIOR_ENGINEER, 
  11.     CONTRACTOR to JUNIOR_ENGINEER -> Blocked("Access for junior contractors is blocked.") 
  12.     else -> throw AssertionError("Unsupported case of $employee and $contract") 

這個(gè)結(jié)構(gòu)讓我的生活變得輕松,也讓 Kotlin 代碼讀寫變得容易,我希望你也覺得這很有用。但它是不是不能用于三元組呢?答案是肯定的。

 
 
 
 
  1. Triple(enum1, enum2, enum3) == enum1 to enum2 to enum3 

以上就是第 1 部分的全部?jī)?nèi)容,如果你仍然很有興趣,請(qǐng)繼續(xù)閱讀第 2 部分。干杯!


網(wǎng)頁名稱:6個(gè)能讓你的Kotlin代碼庫(kù)更有意思的“魔法糖”
網(wǎng)站路徑:http://m.5511xx.com/article/cdgggjg.html