成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

6個(gè)能讓你的Kotlin代碼庫(kù)更有意思的“魔法糖”

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

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

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

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

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

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

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

來(lái)看看下面的示例代碼。

 

  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 工具。

6個(gè)能讓你的Kotlin代碼庫(kù)更有意思的“魔法糖”

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

6個(gè)能讓你的Kotlin代碼庫(kù)更有意思的“魔法糖”

第二步。將 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 提供了很大的靈活性來(lái)允許對(duì)密封類的繼承結(jié)構(gòu)可以被當(dāng)作數(shù)據(jù)聲明甚至對(duì)象來(lái)使用。

 

  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 ,它可能看起來(lái)是那么的丑陋和復(fù)雜?如果你忘記了 Java 語(yǔ)言的一些特性,請(qǐng)?jiān)俅问褂?IntelliJ IDEA Kotlin Bytecode ,但要坐下來(lái)使用 - 這可能會(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ù)來(lái)排列

由于你已經(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)。 第一步,我們來(lá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 來(lái)避免嵌套。
  • 改變枚舉參數(shù)的順序,定義 Pair() 對(duì)象來(lái)讓它更易讀。
  • 合并重復(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)在它看起來(lái)更整潔,但 Kotlin 還有語(yǔ)法糖可以完全省略對(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 部分。干杯!

責(zé)任編輯:未麗燕 來(lái)源: 開源中國(guó)翻譯文章
相關(guān)推薦

2021-02-20 16:01:26

Github前端開發(fā)

2020-12-12 13:50:16

云開發(fā)

2018-06-24 16:39:28

Tomcat異常線程

2021-01-27 13:54:05

開發(fā)云原生工具

2021-06-10 08:15:49

CSS 文字動(dòng)畫技巧

2021-10-28 19:35:02

代碼main方法

2021-03-25 06:12:55

SVG 濾鏡CSS

2012-05-22 10:12:59

jQuery

2022-08-15 22:34:47

Overflow方向裁切

2022-06-15 07:21:47

鼠標(biāo)指針交互效果CSS

2023-05-15 09:16:18

CSSCSS Mask

2017-08-01 00:52:07

kafka大數(shù)據(jù)消息總線

2013-08-28 09:46:09

Debian LinuLinux發(fā)行版

2012-06-19 16:49:19

Web開發(fā)

2024-03-18 08:14:07

SpringDAOAppConfig

2022-07-11 13:09:26

mmapLinux

2009-08-26 17:53:31

C# DropDown

2015-10-28 13:57:29

融合架構(gòu)華三UIS

2010-04-09 11:24:59

Oracle 排序

2021-11-17 10:45:58

Chrome 95新特性前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日本久久福利 | 欧美jizzhd精品欧美巨大免费 | 久久久久亚洲精品 | 亚洲黄色一区二区三区 | 最近中文字幕在线视频1 | 国产精品视频一二三区 | 性色的免费视频 | 在线国产一区 | 欧日韩在线观看 | 欧美精品99 | 午夜欧美一区二区三区在线播放 | 亚洲精品精品 | 亚洲性在线| 免费成人在线网站 | 国产大学生情侣呻吟视频 | 欧美在线观看一区 | 国产精品视频不卡 | 免费毛片在线 | 欧美日韩理论 | 91精品国产91久久久久久不卞 | 日韩欧美国产精品 | 全部免费毛片在线播放网站 | 国产精品资源在线 | 日韩av免费在线电影 | 羞羞网站在线免费观看 | 三级成人片 | 国产片一区二区三区 | 欧美一区二区免费视频 | 久久久观看 | 在线视频h| 伊人色综合久久久天天蜜桃 | 中文日韩在线视频 | 日韩网站在线观看 | 天堂在线网 | 另类视频在线 | 国产一区二区三区 | 亚洲欧美久久 | aaaa一级毛片 | 观看av| 在线观看中文字幕视频 | 成人黄色av网址 |