Kotlin中的“忍者”函數 —— 理解泛型的能力(KAD 12)

来源:http://www.cnblogs.com/figozhg/archive/2017/02/09/6383394.html
-Advertisement-
Play Games

作者:Antonio Leiva 時間:Feb 8, 2017 原文鏈接:https://antonioleiva.com/generic-functions-kotlin/ Kotlin的一些特性組合起來與泛型混合使用創建函數可以極大的簡化你的編碼,且保證它的可讀性。 在Kotlin庫中,有幾個函 ...


作者:Antonio Leiva

時間:Feb 8, 2017

原文鏈接:https://antonioleiva.com/generic-functions-kotlin/

 

 

Kotlin的一些特性組合起來與泛型混合使用創建函數可以極大的簡化你的編碼,且保證它的可讀性。

 

在Kotlin庫中,有幾個函數非常實用,一旦你掌握它們的概念使用起來就非常容易。

 

with函數

 

儘管Kotlin標準庫中有幾個相似的函數,但是,我計劃聚焦在with的各個部分上。

 

這個函數允許做什麼?用了它,我們可以用一變數的代碼塊作為其上下文,這樣就不需要每次使用它重覆它的名字。

 

它們可以替代構建器,不需要為每個類創建特定構建器。

 

例如,回到前面文章的ViewGroup例子,可以轉換這行代碼:

1 val childViews = (0..viewGroup.childCount - 1).map { viewGroup.getChildAt(it) }

 

到:

1 with(viewGroup) {
2     val childViews = (0..childCount - 1).map { getChildAt(it) }
3 }

 

如你所見,括弧內代碼的行為就像是其在本類中。

 

那我們如何得到這樣呢?我們在之前的擴展函數中已經見過了。

 

擴展函數作為其他函數的自變數

 

這事情越來越複雜了,但是這是非常有用的,你需要理解它。

 

你能夠定義擴展函數為另一個函數的參數。

 

你怎樣實現with函數執行前面的例子?最簡單就是這樣:

1 inline fun with(view: ViewGroup, f: ViewGroup.() -> Unit) {
2     view.f()
3 }

 

上面代碼以參數形式接收ViewGroup,且一個用於ViewGroup的擴展函數。ViewGroup可無障礙執行那個函數。

 

但是,這限制較多。對數據的每種類型我們需要一個類似的函數?

 

當然不是。

 

泛型類型

 

我們能夠十分容易地用泛型轉換上面的函數。只需用T替換ViewGroup:

1 inline fun with(obj: T, f: T.() -> Unit) {
2     obj.f()
3 }

 

現在它就可以用於任何類型。例如:

1 with(textView) {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5 }

 

但是,在我們開始討論時,我們忽略一項重要的能力:構建器的角色。

 

泛型類型的返回值

 

如果我們想要一個真正的構建器,我們就需要以某種方式返回構建值:

1 inline fun with(obj: T, f: T.() -> Unit): T {
2     obj.f()
3     return obj
4 }

 

那樣,我們的代碼應該是這樣:

1 val textView = with(TextView(this)) {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5 }

 

註:sp() 是Anko庫的函數,在這系列文章前面談論過它。

 

如果你看函數的正式定義,它非常類似我們已經做的:

1 public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

 

這裡主要的區別在於擴展函數返回的值可能會不同傳遞參數。

 

為了獲得與使用常規函數的相同結果,我們需要這樣做:

1 val textView = with(TextView(this)) {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5     this
6 }

 

最後一行意思是將返回執行擴展函數的對象。

 

其他有趣的函數

 

有一個函數功能非常類似我們在前一節得到的,它叫apply。

 

apply

 

這個函數作為對象的擴展函數,而不是對象的參數:

1 val textView = TextView(this).apply {
2     text = "Hello World"
3     visibility = View.VISIBLE
4     textSize = sp(14).toFloat()
5 }

 

let

 

如果相應的對象不是null,它將只需內部函數的代碼:

1 textView?.text?.let { toast(it) }

 

僅當TextView和text都不為null,text將被顯示在消息框(toast)中。

 

結論

 

結合擴展函數,利用泛型類型的能力,我們能做一些非常有趣的事情。

 

我鼓勵你創建自己的函數以簡化你的日常工作。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者:ASO100鏈接:https://zhuanlan.zhihu.com/p/23041522來源:知乎著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。 自從 8 月中旬蘋果向開發者發佈了一封關於“上傳至 App Store 的 App 可設置一套尺寸相同的截圖“的郵件以來, ...
  • CGRect rectInTableView = [tableView rectForRowAtIndexPath:indexPath]; CGRect rectInSuperview = [tableView convertRect:rectInTableView toView:[tableVie ...
  • public class AntivirusActivity extends Activity { TextView tv_init_virus; ProgressBar pb; Message msg; ImageView iv_scanning; LinearLayout ll_content;... ...
  • 項目中創建表格, 引用頭文件 #import "WBDataGridView.h" - (void)viewDidLoad{ [superviewDidLoad]; // Do any additional setup after loading the view. self.view.backgr ...
  • //左右震動效果- (void)shake:(UIView *)view {CGRect frame = view.frame;CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"posi ...
  • iOS開發常用國外網站清單 原文地址:iOS開發常用國外網站清單作者:eseedo 工欲善其事必先利其器,最近發現臨時查找一些東西容易浪費時間,花了點時間整理一下常用的網站,方便以後備用。 國內的code4app,ui4app,cocoachina,oschina,csdn就不說了,基本上很好用。不 ...
  • 更多博客請訪問http://blog.csdn.net/dylan_lwb_ ...
  • 知識點: 1.UITabBarController使用 2.UITabBarItem使用 關於TabBarController除了本次整理的內容,有興趣的可以看下我以前發過的這兩篇,在實際開發中很實用的東西. RDVTabBarController的基本使用 以及tabbar的防止雙點擊方法 從ta ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...