《Kotlin 實戰》將從語言的基本特性開始,逐漸覆蓋其更多的高級特性,尤其注重講解如何將 Koltin 集成到已有 Java 工程實踐及其背后的原理。本書分為兩個部分。部分講解如何開始使用 Kotlin 現有的庫和API,包括基本語法、擴展函數和擴展屬性、數據類和伴生對象、lambda 表達式,以及數據類型系統(著重講解了可空性和集合的概念)。第二部分教你如何使用 Kotlin 構建自己的 API,以及一些深層次特性——約定和委托屬性、高階函數、泛型、注解和反射,以及領域特定語言的構建。《Kotlin 實戰》適合廣大移動開發者及入門學習者,尤其是緊跟主流趨勢的前沿探索者。
《Kotlin 實戰》教會你使用 Kotlin 語言來開發達到產品級品質的應用。《Kotlin 實戰》為具備一定 Java 經驗的開發者編寫,包含了豐富的示例,和大多數介紹編程語言的書籍相比更加深入,涵蓋了非常有趣的話題,例如怎樣構建使用自然語言語法的 DSL。兩位作者是 Kotlin 的核心開發者,所以你可以相信書中細枝末節的內容都無比地。
● 在 JVM 上進行函數式編程
● 編寫整潔并符合語義習慣的代碼
● 結合運用 Kotlin 和 Java
● 領域特定語言
作者簡介
本書作者為 JetBrains 的 Kotlin 核心開發者!Dmitry Jemerov 從2003年起就在 JetBrains ?作并參與了許多產品的開發,包括IntelliJ IDEA、PyCharm 和 WebStorm。他是 Kotlin 最早的貢獻者之?,創建了最初版本的 Kotlin JVM 字節碼?成器,并且還在世界各地的活動上做了很多關于 Kotlin 的演示。?前他帶領了進? Kotlin IntelliJ IDEA 插件開發的團隊。
Svetlana Isakova 從2011年成為 Kotlin 團隊的?員。她從事編譯器類型推導和重載解析?系統的?作。現在她是?名技術布道者,在各種會議上進? Kotlin 相關討論并從事 Kotlin 在線課程的相關?作。
譯者簡介
覃宇,ThoughtWorks 高級咨詢師,10余年移動應用開發經驗,Android 技術專家,曾為AOSP貢獻過測試用例;目前專注于移動應用的架構設計、自動化測試以及持續交付。
羅麗,高級軟件工程師,移動技術開發顧問,擁有豐富的軟件開發經驗, 熟悉React Native,Android,iOS等多種開發技術。目前任職于ThoughtWorks海外事業部,曾在多個大型移動應用項目中擔任技術顧問。
李思陽,ThoughtWorks咨詢師,移動開發工程師。熟悉Android、Mobile Web相關技術,有著豐富的移動應用開發經驗,在移動應用體驗和兼容性相關領域有獨特的見解;長期關注Android領域相關技術動向。
蔣揚海,ThoughtWorks移動開發咨詢師,深耕Android開發多年,應用開發經驗豐富,對Android開發領域的技術有廣泛的涉獵,對Android技術動向有著敏銳的洞察力。
第 1 部分 Kotlin 簡介 1
1 Kotlin :定義和目的 3
1.1Kotlin 初體驗 3
1.2Kotlin 的主要特征4
1.2.1目標平臺 :服務器端、Android 及任何 Java 運行的地方 4
1.2.2靜態類型5
1.2.3函數式和面向對象 6
1.2.4免費并開源 7
1.3Kotlin 應用8
1.3.1服務器端的 Kotlin8
1.3.2Android 上的 Kotlin 9
1.4Kotlin 的設計哲學 10
1.4.1務實10
1.4.2簡潔 11
1.4.3安全12
1.4.4互操作性 13
1.5使用 Kotlin 工具 14
1.5.1編譯 Kotlin 代碼 14
1.5.2IntelliJ IDEA 和 Android Studio 插件 15
1.5.3交互式 shell15
1.5.4Eclipse 插件 15
1.5.5在線 playground 15
1.5.6Java 到 Kotlin 的轉換器 16
1.6小結16
2 Kotlin 基礎 17
2.1基本要素 :函數和變量 17
2.1.1Hello,world!18
2.1.2函數18
2.1.3變量20
2.1.4更簡單的字符串格式化 :字符串模板 22
2.2類和屬性 23
2.2.1屬性24
2.2.2自定義訪問器 25
2.2.3Kotlin 源碼布局 :目錄和包26
2.3表示和處理選擇 :枚舉和“when” 28
2.3.1聲明枚舉類28
2.3.2使用“when”處理枚舉類 29
2.3.3在“when”結構中使用任意對象 30
2.3.4使用不帶參數的“when” 31
2.3.5智能轉換 :合并類型檢查和轉換32
2.3.6重構 :用“when”代替“if” 34
2.3.7代碼塊作為“if”和“when”的分支 35
2.4迭代事物 :“while”循環和“for”循環 36
2.4.1“while”循環36
2.4.2迭代數字 :區間和數列 37
2.4.3迭代 map 38
2.4.4使用“in”檢查集合和區間的成員39
2.5Kotlin 中的異常 41
2.5.1“try”“catch”和“finally” 41
2.5.2“try”作為表達式 42
2.6小結44
3 函數的定義與調用 45
3.1在 Kotlin 中創建集合 45
3.2讓函數更好調用 47
3.2.1命名參數 48
3.2.2默認參數值49
3.2.3消除靜態工具類 :頂層函數和屬性 50
3.3給別人的類添加方法 :擴展函數和屬性53
3.3.1導入和擴展函數 54
3.3.2從 Java 中調用擴展函數54
3.3.3作為擴展函數的工具函數55
3.3.4不可重寫的擴展函數 56
3.3.5擴展屬性 58
3.4處理集合 :可變參數、中綴調用和庫的支持 59
3.4.1擴展 Java 集合的 API 59
3.4.2可變參數 :讓函數支持任意數量的參數60
3.4.3鍵值對的處理 :中綴調用和解構聲明 60
3.5字符串和正則表達式的處理 62
3.5.1分割字符串62
3.5.2正則表達式和三重引號的字符串63
3.5.3多行三重引號的字符串 64
3.6讓你的代碼更整潔 :局部函數和擴展 66
3.7小結68
4 類、對象和接口 69
4.1定義類繼承結構 70
4.1.1Kotlin 中的接口 70
4.1.2open、final 和 abstract 修飾符 :默認為 final72
4.1.3可見性修飾符 :默認為 public 75
4.1.4內部類和嵌套類 :默認是嵌套類76
4.1.5密封類 :定義受限的類繼承結構79
4.2聲明一個帶非默認構造方法或屬性的類80
4.2.1初始化類 :主構造方法和初始化語句塊80
4.2.2構造方法 :用不同的方式來初始化父類83
4.2.3實現在接口中聲明的屬性85
4.2.4通過 getter 或 setter 訪問支持字段 87
4.2.5修改訪問器的可見性 88
4.3編譯器生成的方法 :數據類和類委托 89
4.3.1通用對象方法 89
4.3.2數據類 :自動生成通用方法的實現 92
4.3.3類委托 :使用“by”關鍵字 93
4.4“object”關鍵字 :將聲明一個類與創建一個實例結合起來95
4.4.1對象聲明 :創建單例易如反掌 95
4.4.2伴生對象 :工廠方法和靜態成員的地盤98
4.4.3作為普通對象使用的伴生對象 100
4.4.4對象表達式 :改變寫法的匿名內部類 102
4.5小結 104
5 Lambda 編程 105
5.1Lambda 表達式和成員引用 105
5.1.1Lambda 簡介 :作為函數參數的代碼塊106
5.1.2Lambda 和集合 107
5.1.3Lambda 表達式的語法 108
5.1.4在作用域中訪問變量 111
5.1.5成員引用 114
5.2集合的函數式 API 116
5.2.1基礎 :filter 和 map 116
5.2.2“all”“any”“count”和“find”: 對集合應用判斷式 118
5.2.3groupBy :把列表轉換成分組的 map 119
5.2.4flatMap 和 flatten :處理嵌套集合中的元素120
5.3惰性集合操作 :序列121
5.3.1執行序列操作 :中間和末端操作 123
5.3.2創建序列 125
5.4使用 Java 函數式接口 126
5.4.1把 lambda 當作參數傳遞給 Java 方法127
5.4.2SAM 構造方法 :顯式地把 lambda 轉換成函數式接口 129
5.5帶接收者的 lambda :“with”與“apply”131
5.5.1“with”函數131
5.5.2“apply”函數 133
5.6小結 135
6 Kotlin 的類型系統137
6.1可空性137
6.1.1可空類型 138
6.1.2類型的含義 140
6.1.3安全調用運算符 :“?:”141
6.1.4Elvis 運算符 :“?:” 143
6.1.5安全轉換 :“as?” 145
6.1.6非空斷言 :“!!”146
6.1.7“let”函數148
6.1.8延遲初始化的屬性 149
6.1.9可空類性的擴展 151
6.1.10類型參數的可空性 153
6.1.11可空性和 Java 153
6.2基本數據類型和其他基本類型 157
6.2.1基本數據類型 :Int、Boolean 及其他158
6.2.2可空的基本數據類型 :Int?、Boolean? 及其他159
6.2.3數字轉換 160
6.2.4“Any”和“Any?”:根類型 162
6.2.5Unit 類型 :Kotlin 的“void”163
6.2.6Nothing 類型 :“這個函數永不返回” 164
6.3集合與數組 164
6.3.1可空性和集合165
6.3.2只讀集合與可變集合167
6.3.3Kotlin 集合和 Java 168
6.3.4作為平臺類型的集合171
6.3.5對象和基本數據類型的數組173
6.4小結 175
第 2 部分 擁抱 Kotlin 177
7 運算符重載及其他約定179
7.1重載算術運算符 180
7.1.1重載二元算術運算 180
7.1.2重載復合賦值運算符183
7.1.3重載一元運算符 184
7.2重載比較運算符 186
7.2.1等號運算符 :“equals" 186
7.2.2排序運算符 :compareTo187
7.3集合與區間的約定 188
7.3.1通過下標來訪問元素 :“get”和“set” 188
7.3.2“in”的約定190
7.3.3rangeTo 的約定 191
7.3.4在“for”循環中使用“iterator”的約定 192
7.4解構聲明和組件函數193
7.4.1解構聲明和循環 194
7.5重用屬性訪問的邏輯 :委托屬性 195
7.5.1委托屬性的基本操作196
7.5.2使用委托屬性 :惰性初始化和“by lazy()”197
7.5.3實現委托屬性198
7.5.4委托屬性的變換規則202
7.5.5在 map 中保存屬性值 203
7.5.6框架中的委托屬性 204
7.6小結 205
8 高階函數 :Lambda 作為形參和返回值 207
8.1聲明高階函數207
8.1.1函數類型 208
8.1.2調用作為參數的函數209
8.1.3在 Java 中使用函數類 211
8.1.4函數類型的參數默認值和 null 值 212
8.1.5返回函數的函數 214
8.1.6通過 lambda 去除重復代碼 216
8.2內聯函數 :消除 lambda 帶來的運行時開銷218
8.2.1內聯函數如何運作 219
8.2.2內聯函數的限制 221
8.2.3內聯集合操作222
8.2.4決定何時將函數聲明成內聯223
8.2.5使用內聯 lambda 管理資源 223
8.3高階函數中的控制流225
8.3.1lambda 中的返回語句 :從一個封閉的函數返回225
8.3.2從 lambda 返回 :使用標簽返回226
8.3.3匿名函數 :默認使用局部返回 228
8.4小結 229
9 泛型 231
9.1泛型類型參數232
9.1.1泛型函數和屬性 232
9.1.2聲明泛型類 234
9.1.3類型參數約束235
9.1.4讓類型形參非空 237
9.2運行時的泛型 :擦除和實化類型參數 238
9.2.1運行時的泛型 :類型檢查和轉換 238
9.2.2聲明帶實化類型參數的函數241
9.2.3使用實化類型參數代替類引用 243
9.2.4實化類型參數的限制244
9.3變型 :泛型和子類型化 245
9.3.1為什么存在變型 :給函數傳遞實參245
9.3.2類、類型和子類型 246
9.3.3協變 :保留子類型化關系 248
9.3.4逆變 :反轉子類型化關系 252
9.3.5使用點變型 :在類型出現的地方指定變型254
9.3.6星號投影 :使用 代替類型參數 257
9.4小結 261
10 注解與反射 263
10.1聲明并應用注解264
10.1.1應用注解264
10.1.2注解目標265
10.1.3使用注解定制 JSON 序列化 267
10.1.4聲明注解269
10.1.5元注解 :控制如何處理一個注解 270
10.1.6使用類做注解參數 271
10.1.7使用泛型類做注解參數272
10.2反射 :在運行時對 Kotlin 對象進行自省 273
10.2.1Kotlin 反射 API :KClass、KCallable、KFunction 和KProperty 274
10.2.2用反射實現對象序列化278
10.2.3用注解定制序列化 279
10.2.4JSON 解析和對象反序列化283
10.2.5反序列化的一步 :callBy() 和使用反射創建對象 287
10.3小結 291
11 DSL 構建 293
11.1從 API 到 DSL 293
11.1.1領域特定語言的概念 295
11.1.2內部 DSL296
11.1.3DSL 的結構 297
11.1.4使用內部 DSL 構建 HTML298
11.2構建結構化的 API:DSL 中帶接收者的 lambda 299
11.2.1帶接收者的 lambda 和擴展函數類型 299
11.2.2在 HTML 構建器中使用帶接收者的 lambda 303
11.2.3Kotlin 構建器 :促成抽象和重用307
11.3使用“invoke”約定構建更靈活的代碼塊嵌套 310
11.3.1“invoke”約定 :像函數一樣可以調用的對象 310
11.3.2“invoke”約定和函數式類型 311
11.3.3DSL 中的“invoke”約定 :在 Gradle 中聲明依賴 312
11.4實踐中的 Kotlin DSL 314
11.4.1把中綴調用鏈接起來 :測試框架中的“should” 314
11.4.2在基本數據類型上定義擴展 :處理日期 316
11.4.3成員擴展函數 :為 SQL 設計的內部 DSL317
11.4.4Anko :動態創建 Android UI 320
11.5小結 322
A 構建 Kotlin 項目 323
B Kotlin 代碼的文檔化 327
C Kotlin 生態系統 331
譯者序
當收到這本書的翻譯邀請時,我們的內心是激動的,終于有機會將自己喜愛的語言系統地介紹給中國的開發者,而且是通過口碑頗佳的實戰系列。此時,正值2017 年度的 Google I/O 召開前夕,接下來重磅消息大家都知道了 :在 Google I/O 大會上,Kotlin 正式成為了官方的 Android 開發語言,迅速占據了國內各大技術媒體的頭條。一夜之間,所有的 Android 開發者都迫切地想搞清楚它的來龍去脈。Kotlin究竟是何方神圣,為什么是它?
這一點兒也不奇怪。對于博學 Android 開發者來說,Kotlin 早已不是新鮮的概念了。早在 2015 年 1 月,Android 開發者社區大神 Jake Wharton 就了一篇使用Kotlin 來進行 Android 開發的總結。那時開始,不少頂尖的開發者和公司就開始嘗試在正式的 Android 項目中使用 Kotlin 語言 ;我們也從 2015 年開始在多個項目上使用了 Kotlin 語言。它帶給我們的體驗,和帶給所有其他實踐過 Kotlin 語言的開發者的一樣 :它的發明者 JetBrains 所言非虛,這是一門簡潔、安全、實用的語言,用了就停不下來,就忍不住地想推薦給周圍的人。我們理所當然地把 Kotlin 放在了今年及時季度 ThoughtWorks 技術雷達的評估象限 :https://www.thoughtworks.com/radar/languages-and-frameworks/kotlin。
Kotlin 讓人愛不釋手的最重要原因就是來自 JetBrains 的基因。作為最負盛名的IDE 創造者,JetBrains 深諳開發者的需求,孜孜不倦地追求給開發者提供最實用、較高效的 IDE,包括 Android Studio、IntelliJ、RubyMine 等。由這樣想開發者之所想的公司創造出來的語言,又怎么會不受開發者熱捧呢?所以 Gradle、Spring,以及越來越多的庫、框架和工具也陸續加入到了支持 Kotlin 的陣營。
本書深入淺出地介紹了 Kotlin 語言的方方面面,從最基礎的語言要素到如何定制自己的 DSL 都有涉及。相信讀者閱讀本書并嘗試之后一定會愛上這門語言,但把 Kotlin 應用到自己的項目中會不會有什么風險呢?讀者們大可不必擔心,以往的經驗告訴我們,整個過程無縫無痛。首先,Kotlin 足夠簡單,對于初學者來說掌握也不算困難,兩三天就可以上手 ;其次,Kotlin 和 Java 可以無縫地銜接,可以在遺留項目上和 Java 混用 ;,編譯器的靜態檢查和 IDE(必須是 JetBrains 出品的 IntelliJ IDEA 或者 Android Studio)強大的輔助功能,可以幫你發現很多問題(例如空指針異常)并將其自動消除在搖籃之中。有的讀者會說,但我還沒有用過這些IDE 啊?那你還在猶豫什么,請立即使用它們來提高你的生產力吧!這也算是使用Kotlin 帶來的額外收獲。
從 Kotlin 成為 Android 開發語言的那一刻開始,我們熱情高漲地投入了幾乎全部業余時間到本書的翻譯工作,終于在最短的時間內把它呈現在廣大讀者面前。這一切還要感謝本書的編輯和所有譯者家人在背后的默默付出。由于譯者水平所限,難免出現謬誤遺漏,還望讀者海涵斧正。
覃宇、羅麗、李思陽、蔣揚海
2017 年 6 月于 ThoughtWorks 成都
序
當我在 2010 年春季及時次拜訪 JetBrains 的時候,我相當確定世界上不需要另一種通用編程語言了。我認為現有的 JVM 上的語言已經足夠好了,誰會有想法去創建一門新語言呢?在經過大約一個小時的關于大規模代碼庫上產品問題的討論后我被說服了,并且后來成為 Kotlin 一部分的最初想法就已經被描繪在白板上。很快我就加入了 JetBrains 來主導這門語言的設計與編譯器的開發工作。
到今天,六年多的時光過去了,我們也快要第二個版本。我們已經擁有超過 30 人的團隊和數以千計的活躍用戶,還有很多讓我們難以輕易實現的精彩的設計理念。但是不要擔心,這些想法在進入這門語言之前還必須經過縝密的考察。我們希望這本書的篇幅依然能夠容得下 Kotlin 的未來。
學習一門編程語言是一個令人興奮而且常常是回報頗豐的嘗試。如果它是你的及時門語言,通過它你能學到整個編程的新世界。如果不是,它會使你以新的術語來思考熟悉的東西,從而以更高層次的抽象來更深入地了解它們。本書主要針對后者,即面向已經熟悉 Java 的讀者。
從頭開始設計一門語言可能是一項具有挑戰性的任務,但是使其與另一門語言融洽的工作就是另一回事了——尤其是那門語言還包含了許多的憤怒的食人魔,以及一些陰暗的地牢(在這一點上你如果不相信可以去問 C 的創造者 Bjarne Stroustrup)。與 Java 的互操作性(這就是 Java 與 Kotlin 之間是如何互相混合調用的)是 Kotlin 的基石之一,本書也投入了很多的注意力在這一點上。互操作性對于在一個已有的 Java 代碼庫中逐步地引入 Kotlin 非常重要。即使從頭開始開發一個新項目時,也必須考慮到能夠將這門語言融入一個擁有更大圖景的平臺中去,而以 Java 編寫的所有函數庫就是這樣的一個平臺。
當我在編寫本書時,兩個新的目標平臺正在開發 :Kotlin 現在可以在 JavaScript虛擬機上運行以支持全棧 web 開發,并且還將很快能夠直接編譯成原生代碼,從而在需要的時候能夠脫離任何的虛擬機來運行。 1 所以,雖然本書是面向 JVM 的,但是你從中學到的很多東西也是可以應用于其他運行環境的。
本書作者從項目伊始就已經是 Kotlin 團隊的成員,所以他們對語言本身和內部實現非常熟悉。他們在會議演講、研討會及 Kotlin 課程方面的經驗使他們能夠對預期的常見問題及可能的陷阱,提供良好的闡述。本書既闡釋了語言特征背后的高級概念,也提供了足夠深入的細節。
希望你能享受與我們的語言及本書相處的時光。正如我經常在我們社區的帖子中說的那樣 :使用 Kotlin 愉快!
ANDREY BRESLAV,JetBrains Kotlin 首席設計師
開發者想完成他們的工作——同時越省事越好。使用 Kotlin 編碼就意味著省事。Kotlin 編程語言提供了賦有表現力的語法,強大直觀的類型系統和美妙的工具支持,還有與現存 Java 代碼、庫及框架無縫的互操作性。Kotlin 可以被編譯成 Java 字節碼,所以你可以在所有使用 Java 的地方使用它,包括 Android 在內。借助高效的編譯器和標準庫,Kotlin 在運行時幾乎不用承受任何額外開銷。
——kotlin核心開發者
“既闡釋了高級概念,也提供了足夠深入的細節。”
— 摘自 Kotlin 首席設計師 Andrey Breslav 作的序
“這本書保持了 Manning 實戰系列的水準,滿足了你快速提高生成力的所有需要。”
— Kevin Orr, Sumus Solutions
“有這本書指導你,Kotlin 學起來有趣又簡單!”
— Filip Pravica, Info.nl
“寫得非常,非常好,淺顯易懂。”
— Jason Lee, NetSuite
這書可以,好好學習
我很喜歡新事物
好書,印刷清晰內容強!我喜歡
紙張還行 主要是送貨快
非常好,入門kotlin就靠它了,很棒
不錯正品 值得買,包裝也挺好的,這個價錢值了
已經開始看了,加油。
很好,學習無止境,程序猿!
書還不錯。
很有幫助,學到了很多
書就不多說了,當當也是專門賣書的電商,每次在當當賣書都是一個塑料袋套書。運輸過程中各種暴力。主皮被不明尖物體扎了兩個眼,另一本書角明顯是被暴力仍后落地,書角都仍嘿了。包裝差評差評差評
新技術,趕緊買一本看看
很好!快遞員也很好,速度很快
經典之作,學習Kotlin的好書
不錯,沒破損
幫朋友買的,用來自學。
這本書還不錯
常閱可修身養性可陶冶性情可勵志也是我們洞察世界的途徑現實一點說就是古人說的
111111
還沒看,中文版就這一本,先買著有時間學習一下