當前位置:
首頁 > 最新 > Kotlin介紹:Part 2

Kotlin介紹:Part 2

Extension Functions擴展功能

Higher order functions高階功能

Type Parameters and Generics鍵入參數和泛型

Delegates代表

Namespaces, Modules, and Scoping命名空間,模塊和作用域

在Kotlin簡介:第1部分,我們介紹了基本的語法,現在我們可以看看實際上哪些方面使Kotlin受歡迎。 在這篇文章中,我們將介紹幾個集合和lambdas,一些方便的擴展功能(,,&),安全性,我們將接觸一些類型。 我們在這篇文章中將介紹很多,所以準備好了。 如果你想直接跳轉到泛型,委託和擴展功能,請期待Kotlin簡介:第3部分。O(∩_∩)O~

Kotlin Collections and Lambdas

Kotlin最有趣的部分之一是其收藏庫(collection library)和相關的方法。你需要知道的關於這個的事情有兩個方面:右邊是「不可變的」一面,左邊是可變的集合。Kotlin非常堅持告訴你,有區別 。像Kotlin一般的語言一樣,collection在很大程度上依賴於不變的一面。這使得功能編程模式特別有用,如果不是您的編程風格必不可少的。不變性還為您提供了一些餘地,減少了對並行性和並發性的負擔,這篇文章不涉及到這一點[1]。

那麼Kotlin系列是什麼?如果您熟悉Java 8, 您將會對這些收集方法(Java流)和習語十分了解。然而,Kotlin提供了大部分你可以想到的東西(幾乎沒有你不能)的延伸。我們來看看吧。

Kotlin為您提供幫助方法來創建容器。我在這裡列出了列表,設置和映射這兩個不可變的和可變的版本。請注意,我們的地圖聲明中的to實際上是一個中綴函數,而不是一個關鍵字[2]。 Kotlin系列的真正功能除了默認的不變性外,還來自於Kotlin stdlib的擴展功能。如果您熟悉功能編程,您將熟悉大部分功能。它們是一組幫助函數和更高級的函數,可以為您的集合提供常用的操作。通過這些擴展功能,我們可以將所有常見的疑犯,如map,flatMap,forEach,fold,reduce,filter,zip等等。

在我們可以使用這些之前,我們需要談談Kotlin的一件重要事情:lambdas。 Kotlin標準庫的收藏擴展功能的優點來自易於使用的lambdas,只需使用足夠的類型推理來增強編程人員的安全性。在Kotlin中有幾種方法來定義lambda函數。

在第一個例子中,我們可能定義了Kotlin lambdas最常見的用法。我們可以用角括弧縮寫匿名函數。我們還可以選擇我們的lambda中的參數的名稱(我們在這裡省略了類型定義;我們可以從aList列表中看到它是一個Int),在這種情況下是elem。然後我們定義我們的lambda的體。不需要返回語句,最後一行將被返回。

下一個例子進一步說明,甚至省略參數定義。在Kotlin中,默認情況下,一個參數lambdas會收到名為的參數。這是有道理的,因為我們知道我們正在努力;沒有必要命名的東西。請注意,過多使用itism,尤其是在嵌套函數中,會導致非常混亂的代碼。在簡單的一次性案件或延續案件中,這些都是罰款和花花公子。在更複雜的情況下,最好輕視。

最後一個向我們介紹幾個新概念。首先是一個本地函數[3],我們引用了一個雙匯法語法,我們從Java 8熟悉(儘管沒有必要用靜態關鍵字或類名來混淆這個美麗)。本地函數的外觀和作用與類或全局作用域函數非常相似,但作為一個附加,它還可以訪問與函數本身在同一範圍內定義的變數。引用本地函數的第二種方法是簡單地將它稱為我們的lambda,就像在注釋部分中顯示的那樣。

正如你所看到的,Kotlin中的lambdas是以直截了當的方式定義的。它們在您的代碼庫中也非常明顯,並使得高階函數的使用變得輕而易舉。關於Kotlin和lambdas的最好的部分是類型推斷,當類型不排隊時,它會給你一個紅色的sigiggly線在您的代碼下。通過編譯器的這種幫助,您可以將精力集中在實際的業務邏輯上,而不是試圖找出循環應該遍歷多少次。

有關Kotlin收集擴展功能的更多信息可以在官方網站API文檔中找到(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/index.html#functions),或者您可以查看快捷方式,並在此處查看方便的備忘單(http://jussi.hallila.com/Kollections/)。在介紹性帖子中,提及的容器擴展功能太多了。

Null safety

如果您瀏覽Jetbrains網站關於Kotlin,您將會看到他們如何宣傳Kotlin的「Null safety」作為主要標題之一。 這是什麼意思?

在Kotlin中,您的Kotlin代碼具有絕對的無效安全性,與您互操作的其他JVM代碼相對無效。 Kotlin編譯器非常嚴格的解剖你所寫的代碼,當涉及到可空性。 如果定義一個可能為null的變數,則需要將其定義為可空。 這個Kotlin編譯器可以弄清楚,如果你能使用你的變數做一個天真的調用,或者你需要對它進行一個空的檢查。 這在實踐中如何工作?

這三個變數聲明有兩個可空值和一個非空值。 無效性的共同點是問號; 可空變數和函數參數用問號定義,not-nulls沒有它。 這個問號在Kotlin「null safe」代碼中起著重要的作用。 如果Kotlin編譯器在變數聲明或函數參數/返回類型中看到這個問號,它將強制您對其進行空檢查。 如果您主要撰寫Kotlin代碼,那麼您可以從可空的代碼中引導出來。 然而,Kotlin與Java高度互操作,因此當您觸摸Java世界時,您必須假設傳遞的一些數據可能為空。Kotlin提供了一些幫手處理這個價值十億美元的錯誤。

如果您嘗試這樣做,您將看到Kotlin編譯器將如何呻吟。 在IntelliJ中,您將在文本下方獲得一個紅色的波浪線。 它會呼喊只有安全(?)或非空斷言(!!.)調用允許在類型為Lad的可空接收者。 為了解決這個問題,你幾乎沒有選擇。

第一個例子是舊的,可信的非空檢查。 我們知道這是一個很好的做法,並且已經在其他語言中使用它了。 編譯器知道,在空檢查完成後,我們可以使用我們的變數,所以波形線將從print語句中消失。 在第二個例子中,我們看到一些魔法。 已經熟悉的問號是再次出現的,但這一次在不同的角色。 在這個上下文中,問號說If laddy不為null,然後從其中取名稱屬性。 如果laddy為null,那麼null將被列印到控制台中。

第三個函數引入了一種新的擴展函數,我們可以使用這個函數叫做let。 我們會在幾分鐘後回到那裡,但是首先我們將把安全性放在一起,看看這個精美的elvis操作符。 如果我們要從我們的函數返回一些東西,我們可以使用elvis作為默認值,以防我們碰到一個null。 使用elvis有點像這樣:

正如你所看到的,我們使用安全的呼叫運算符來表示它們的名字。 如果這兩個研究員的後者是空的,我們將返回「James」; 如果前者為null,我們仍然會返回「James」,因為我們永遠不會實際達到登錄訪問嘗試。 只有這兩個都不為空,我們才會返回名字。 這是有道理的,因為這真的是我們可以安全地返回實際名稱的唯一方式。 我們在這個神秘的let函數中使用了同樣的雙重安全性,在前面的代碼塊中顯示出很少的排列。 現在我們可以仔細看看這個和它的同胞了。

Extension functions: Apply, Let, Run, and With

Kotlin推出了一些擴展功能,可幫助我們應用和調用範圍。 我們看到的第一個 let是一個擴展,它將一個參數lambda作為參數。 向上滾動幾隻滑鼠,再看看代碼示例。 唯一要做的就是調用我們已經傳入的lambda,並將其用作lambda的唯一參數。 在這種情況下,這意味著我們的對象的name屬性,但只有當laddy和name都不為null時。 讓我們只操作存在的價值觀; 作為擴展,它不能擴展不存在的東西!

應用是另一個時髦的擴展功能,我們可以在許多情況下使用。 這個方便的傢伙的一個常見用法是創建一個需要許多調用的對象,但是沒有很好的功能來做到這一點。 為了簡單起見,我們可以想到Java bean及其getter和setter。 這是Java代碼!

呃,看起來有點醜陋嗎? 讓我們一起跑(哈哈)不管。 我們將跳回Kotlin一側。

Excellent,已經很舒服了 看看我們如何在我們的應用函數中調用setter方法。 我們的mrBean現在是一個完全的對象,其中包含wild和erbeest。 在Kotlinsetter和getter是默認的方法了。 它們被當作屬性被視為來自Java,並且與上述相同的代碼可以這樣寫:

更好,更簡潔。 應用有很多有用的功能,但這是我最喜歡的功能。 它接收一個它所調用的lambda函數,然後返回它,這是原始對象。 因此,在適用範圍內的價值是所要求的對象。

接下來,我們有。 這個傢伙類似於申請,有一個小小的警告。 它實際上不是一個擴展函數,只是一個函數,它接受兩個參數,並用於對象的上下文。 使用with有點皺眉,因為它有時候有些不可讀的代碼。 我們來看一個例子。 我們將使用我們之前定義的

[4]

非常類似於apply,你不覺得嗎? 一點都不! 我們有點被欺騙,因為我們沒有做任何返回值。 它返回with塊中最後一個表達式的值。 這是一個重要的區別,所以讓我們看看一個更好的例子。

Sneaky?

我們將繼續。

這個函數叫做run是一個非常簡單的小事情。 它是一個擴展函數,它接收一個參數,一個lambda。 它只是調用該lambda並返回該lambda的響應。 「那麼這傢伙怎麼用?」你可能會問。 我也是 當我想運行時,我看到兩個用例。 使用它來運行某些東西,當且僅當它被調用的對象不是null(使用它類似於上面的幾行,但在運行情況下這是作為範圍的對象)或使用它來調用我們的函數調用和保護我們的lambdas。 我們必須記住,該運行與之相同,但通常更容易遵循,因為我們將其稱為保證的非空對象,並且我們傾向於更加意識到該對象的範圍。

Types: Checking, casting, aliasing, and safety

在Java世界中,如果像(clazz instanceOf SomeClass)這樣的檢查,程序員想看看他們是否正在正確地實現其介面或擴展的基類,那麼您可能會遇到這樣的錯誤。當從一個更通用的類轉換到更具體的類時,你可能也看到很多括弧。這似乎在應用程序的邊界發生了很多,無論是資料庫訪問,API調用還是傳入的JSON。 Kotlin在許多方面與Java類似,這也是其中之一。可能需要投射並檢查您的類型,看看您正在使用正確的實現。幸運的是,科特林提供了一些幫助者,讓我們有機會以安全的方式進行這些檢查。我們來看一下我們可以做什麼,而不必太多的類型理論。

在Kotlin中的類型推斷是非常好的,編譯器在編寫代碼時給出了很多有用的提示和提示。當你需要檢查一個對象是否是某種類型時,你可以使用是關鍵字。

在上面的塊中,第一個函數將失敗,並且根本沒有實際的編譯。 它會呻吟給你,它找不到匹配類型的加號功能。 第二個功能修復:它做一個簡單的檢查,而在這一點Kotlin智能將該值轉換為Int,因此它可以在if語句中使用。 通常你可能會更多地絆倒,當談到的是支票,就像這樣:

這個例子與以前看過的if語句是一樣的,但是它不會更美觀嗎?

現在,我們已經感動是,當我們一起可拿一個小的彎路,談談密封類。 Kotlin有一個密封類的概念,我們可以把它看成是一些子類的包裝。

如果我們有這樣一個結構,一個密封的超類和三個孩子可以擴展它,我們可以很好地處理我們的多態情況,並結合when和is。

我們新的和修改的getTheAnswer函數不能編譯。 當我們告訴我們,當表達必須是窮盡的時候,我們會得到一個詭計的線。 甚至會告訴我們從我們的when語句中我們丟失了哪些子類。 如果我們添加我們的KissFromARose在那裡,所有的將是盛大的,像愛爾蘭人說的。 我們還得到不需要在其中添加else子句的附加好處。 科特林已經知道我們已經涵蓋了所有的情況。

上面的編譯很好,當我們在潛意識中通過代碼庫,晚上給我們安心。 如果您正在使用密封類,那麼儘可能省略else行。 這樣,每個新的子類很快將使您的編譯失敗。

有時,我們還需要做一些類型的鑄造。 在Kotlin,這是用關鍵字完成的。 當它附加到值時,我們可以假定它被轉換為該類型。 這個小功能也有一些內置的優點。 在Java世界中,你可能習慣為被轉換的對象分配一個新的變數,但是不要擔心,在Kotlin中沒有必要。 當被拋出一次時,編譯器知道我們的變數被轉換為別的東西。 沒有任何更多的喘氣和喘氣的需要。

上面的例子再次無法編譯。 capitalize()被加下劃線,編譯器告訴我們有一個未解析的引用和解析器類型不匹配。 這是非常有道理的,因為我們知道Any沒有capitalize()函數。 解決這個問題很容易。 我們將變數轉換成String,並且神奇地,我們的大小寫就像一個魅力。

Kotlin做得很好,可以幫助你,特別是在你使用了很多泛型,面向對象和深層繼承層次的情況下。 如果你幸運的是在代碼庫中看不到這些行,我有點嫉妒你。

關於Kotlin類型的最後一件事是類型別名。 有時候,特別是當你得到一個複雜的函數類型時,類型聲明就會變成很大的比例。 類型別名可用於縮短功能類型或具有多種類型參數的一些通用類型。 別名不要去檢查實際的實現,它們只是底層類型的同義詞。 Kotlin不像Haskell那樣有新的類型,但是鍵入別名是某種方式。 使用Kotlin和類型別名,我們仍然可能發生災難。

這是Kotlin的有效代碼; 它編譯並運行良好。 所以,在這種情況下,我們的類型並不為我們提供很多額外的好處。 類別別的真正好處就是這樣的:

那個傢伙還是很長,但至少比打入完整的lambda簽名和返回值要短一點。 當使用類型別名時,您可以輕鬆地過多地丟失您的功能的基本類型。 當正確使用和良好的預想時,鍵入別名將給你一個漂亮和可讀的類型簽名為您的API。

我們現在已經介紹了Kotlin的集合,零安全性和類型安全性。

在介紹Kotlin第1部分,我們介紹了語法,變數,函數和類 。

還有幾個討論的話題,即泛型和代表,擴展功能和具有更高階功能的功能風格,以及Kotlin創建類型安全DSL的能力。 這些將在第3部分中介紹。

因為不管所有的幫手,這仍然是一個困難的話題。

Kotlin中的一個中綴函數是一個函數,它接受一個參數,是一個成員函數或擴展函數。 在Kotlin 1.to(2)可以重寫為1到2哪裡是Pair類的擴展功能。 在科特林地圖上,收集一對對象作為他們的物品。 是的,理論上你可以編寫整個應用程序,而不需要觸摸。 所有人物! (雖然那裡的樂趣在哪裡,因為IntelliJ幾乎可以看清你的想法,並自動完成所有的事情。)

是的,在Kotlin中,您可以定義任何地方的功能,甚至在其他功能中。 當您構建複雜的封閉結構並希望通過命名它們來保持功能時,這非常方便。

當您記住它需要兩個參數時,函數調用看起來有點時髦。 在Kotlin中,如果第二個(嗯,最後一個)參數是一個函數,我們可以關閉括弧,使lambda看起來就像在外面。 它仍然是我們調用的相同的功能,而lambda仍然是我們傳入的第二個參數。這使得Kotlin成為DSL的精湛語言,因為我們可以很容易地創建這些代碼塊。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 公眾號 的精彩文章:

蘋果的WWDC大會又發布了吊炸天的東西
實力詩人︱周綠森:你不愛我
梁濤:詩和遠方的背後
中國的銀行標牌書法是誰寫的?
混元如在之神魔同心

TAG:公眾號 |

您可能感興趣

Spring Boot與Kotlin使用Spring-data-jpa簡化數據訪問層
Kotlin項目下的Retrofit2網路請求框架
Gradle Kotlin DSL的accessors 生成問題
Spring Boot與Kotlin 使用MongoDB資料庫
Kotlin Android 環境搭建
Kotlin 介面
Kotlin 繼承
Kotlin和Swift語言在Redmonk榜上排名大幅提升
Canonical宣布Kotlin編程語言Snap包格式上線
Kotlin打造Android路由框架
Kotlin語言Web庫又添一虎將:Kweb
Kotlin 泛型
開發 iOS 應用,Kotlin Native 是否夠格?
Google發布Android KTX預覽版,它能為Kotlin開發者做些什麼?
Kotlin 語言獲Linux通行證
Kotlin 編程
Kotlin 類和對象
Kotlin 擴展
Android開發者是時候轉向Kotlin了
Kotlin 威脅、Python 逆襲,2018 年程序員需要升級哪些技能?