Kotlin 學習筆記08

Lambda作為形參和返回值

聲明高階函數

  • 任何以lambda或者函數引用作為參數的函數,或者返回值,或者兩者都有,就是高階函數。比如list.filter
    (4,"abc")-> {} 如下:

{ x, y -> x + y} 這里省略了參數x,y類型,因為在其他部分已經制定了,不需要在lambda函數體再次聲明

val funOrNull: ((Int, Int) -> Int)? = null
復制代碼
  • 可以為函數參數制定名字
//聲明
fun performRequest(url: String,callback: (code: Int, content: String) -> Unit
){}
//調用
val url = "http://baidu.com"
performRequest(url,{code, content -> /*code*/ })
performRequest(url){code, content -> /*code*/ }//根據kotlin約定,lambda為最后一個參數,可以放到括號外面
復制代碼
  • 調用函數
//聲明一個函數,參數為一個函數,這個函數有2個參數都是int值,返回值也為int
fun towAndThree(operator: (x: Int, y: Int) -> Int) {//這里的x,y是可以省略的,省略了,IDE代碼補全會不方便val result = operator(3, 4)print("the result is $result")
}
復制代碼
  • filter()函數
//聲明
public inline fun <C : Appendable> CharSequence.filterTo(destination: C, predicate: (Char) -> Boolean): C {for (index in 0 until length) {val element = get(index)if (predicate(element)) destination.append(element)}
return destination
}
//調用
println(url.filter { it in 'a'..'z' })
復制代碼

  • 在Java中使用函數類 原理:函數類型被聲明為普通的接口:一個函數類型的變量,是FunctionN接口的一個實現。Kotlin標準庫定義了一系列的接口比如 Function0<R>(沒有參數的函數),Function1(P1,R)(一個參數的函數),調用這個方法就會執行函數。一個函數類型的變量就實現了對應的FunctionN接口的實現類的實例,實現類invoke方法包含了lambda函數體
//kotlin聲明
fun processTheAnser(f: (Int) -> Int){}
//java 調用 java 8
processTheAnder(num->num+1)
//在Java8以下的版本這樣調用
procressTheAnder{new Function1<Integer,Integer>(){@Overridepublic Integer invoke(Integer number){return number + 1}}
}
復制代碼

函數類型的參數默認值和null

fun <T> Collection<T>.joinToString(separator: String = ", ",prefix: String = "",postfix: String = ""
): String {val result = StringBuilder(prefix)for ((index, value) in this.withIndex()) {if (index > 0) result.append(separator)result.append(value.toString())}result.append(postfix)return result.toString()
}
復制代碼

返回函數的函數

  • 比如運輸費用依賴于運輸方式,可以定義一個函數,用來選擇恰當的邏輯變體,并將它作為一個函數返回
fun getShoppingCarCacul(delivery: Delivery): (Order) -> Double {if (delivery == Delivery.STANDARD) {return { order: Order -> 6 + 2.1 * order.itemCont }}return { order -> 1.2 * order.itemCont }
}
//調用
var shoppingCarCacul = getShoppingCarCacul(Delivery.EXPEDITED)
println("產生的運費:${shoppingCarCacul(Order(4))}")
復制代碼
  • eg:通過輸入開頭文字,過濾聯系人列表
data class Man(val firstName: String,val lastName: String,val phoneNumber: String?
)class ContactListFilter() {val prefix = ""val isOnlyPhoneNumber = falsefun qetPredicate(): (Man) -> Boolean {val startWithPrefix = { man: Man -> man.firstName.startsWith(prefix) || man.lastName.startsWith(prefix) }//這里不能使用it,因為IDE推斷不出it代表是什么if (!isOnlyPhoneNumber) {return startWithPrefix}return { man: Man -> startWithPrefix(man) && man.phoneNumber != null }//這里可以是用it,這里是根據方法的返回值類型,推斷出it代碼得man}
}
//調用val mans = listOf(Man("Bob", "jack"), Man("BooBo", "jack", "13800138000"), Man("kk", "jack", "13800138000"))val contactListFilter = ContactListFilter()with(contactListFilter) {prefix = "B"isOnlyPhoneNumber = false}
println(mans.filter(contactListFilter.qetPredicate()))
復制代碼

使用lambda去除重復代碼

 val log = listOf(SiteVisit("/", 34.0, OS.WINDOWS),SiteVisit("/", 22.0, OS.MAC),SiteVisit("/", 12.0, OS.WINDOWS),SiteVisit("/sign_up", 8.0, OS.IOS),SiteVisit("/", 16.3, OS.ANDROID))
fun List<SiteVisit>.averageTime(os: OS) = filter { it.os == os }.map { it.duration }.average()//調用
println(log.averageTime(OS.WINDOWS))
復制代碼
  • 如果說要查詢WINDOW、和Android的呢?后面又需要改成來自iOS的注冊頁面停留時間是多少呢?這個時候lambda就派上用場了。
fun List<SiteVisit>.averageTime(predicate: (SiteVisit) -> Boolean) = filter(predicate)//這里的篩選改為lambda。.map { it.duration }.average()
復制代碼

把過濾條件轉換成lambda表達式,實現去除重復代碼
策略模式(你需要聲明一個接口,并且為每一種可能實現不同的策略)可以通過lambda簡化

內聯函數:消除lambda運行時帶來的開銷

在kotlin中,每創建一個lambda表達式就會創建一個匿名類,so,每次調用都會創建一個對象,會帶來額外的開銷這個時候inline就出現了。
一個被inline修飾的函數,函數體會直接替換到函數被調用的地方,而不是正常調用。一般來說,參數如果被直接調用或者作為參數傳遞給另外一個inline函數。他是可以被內聯的。

  • 內聯函數使用限制-》不能把內聯函數保存到一個屬性?

內聯集合操作

Kotlin標準庫中,集合函數,比如filtermap等函數已經inline函數,不會產生額外的對象。在處理比較大的集合,應該使用序列asSequence進行操作。

怎樣決定是否使用lambda

  • 使用inline關鍵字只能提高帶有lambda參數的函數的性能。
  • 對于普通函數JVM已經提供了強大的內聯支持。
  • 應該保證inline修飾的函數比較小。-》因為需要把函數字節碼拷貝到每一個調用點上。

使用lambda管理資源

通常在資源管理中,需要在try里獲取資源,在finally中釋放資源可以把這一部分封裝成lambda表達式 在Kotlin中,加鎖使用withLock函數 :try-with-resource 語句

static String readFirstLineFromFile(String path) throws IOException {try (BufferedReader br = new BufferedReader(new FileReader(path))) {return br.readLine();}//這里不需要寫關閉資源的語句,
}
復制代碼

在Kotlin中使用use實現相同的結果,用于操作可關閉的資源。

fun readFirstLineFromFile(path: String): String = BufferedReader(FileReader(path)).use { br -> br.readLine() }
復制代碼

高階函數中的控制流

  • 使用return 從一個封閉的函數中返回。
val list = listOf(Person("Bob", 18, 20000), Person("Jack", 19, 20000))list.forEach {if (it.name=="Bob") {println("Found!")return //直接返回方法}}
復制代碼
  • 從lambda返回
val list = listOf(Person("Bob", 18, 20000), Person("Jack", 19, 20000))list.forEach {if (it.name=="Bob") {println("Found!")return@forEach //直接返回方法}}
復制代碼

同樣的規則也適用于this表達式

  • 匿名函數:默認使用局局部返回
list.forEach {if (it.name=="Bob") returnprintln("Found!")}
復制代碼

filter中使用匿名函數

    list.filter(fun(person): Boolean {return person.age > 10})
復制代碼

如果是使用表達式函數體,可以省略返回值類型,可以簡化為

list.filter(fun(person) = person.age > 10
)
復制代碼

End

轉載于:https://juejin.im/post/5c3d728af265da61171cf3c3

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/449651.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/449651.shtml
英文地址,請注明出處:http://en.pswp.cn/news/449651.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一個開源工作者對開源與賺錢的一些想法

摘要&#xff1a;本文作者長期以來一直定期為開源世界貢獻代碼&#xff0c;最近重新思索了一下開源軟件的意義&#xff0c;在開發者中引起了強烈共鳴。 15年來&#xff0c;我一直定期地貢獻開源代碼&#xff0c;但是現在我停下來思考這對我自己究竟意味著什么&#xff0c;也許僅…

Chapter 5 Blood Type——33

We were near the parking lot now. 我們現在離停車場不遠。 I veered left, toward my truck. Something caught my jacket, yanking me back. 我轉向左邊&#xff0c;面對我的車。有人抓住了我的夾克讓我回過神來。 "Where do you think youre going?" he asked,…

CentOS上安裝Docker (圖解)

更簡單的辦法&#xff1a;三分鐘裝好 Docker ( 圖解&#xff09; 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 // 用上面那個辦法吧&#xff0c;簡單多了&#xff0c;下面這個方法看看…

Uber提出有創造力的POET:自行開發更困難環境和解決方案

近日&#xff0c;Uber 發文介紹了一種開放式方法 POET&#xff08;Paired Open-Ended Trailblazer&#xff09;&#xff0c;可自行開發難度遞增的環境及其解決方案&#xff0c;還可以實現不同環境中的智能體遷移&#xff0c;促進進化。Uber AI 實驗室注重開放性&#xff08;ope…

spring boot 報錯:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default p

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 ** WARNING ** : Your ApplicationContext is unlikely to start due to a ComponentScan of the default package. Your ApplicationCo…

jl1.如何設置元素的寬高包含元素的邊框和內邊距

jl1.如何設置元素的寬高包含元素的邊框和內邊距 方法一&#xff1a; 文檔地址&#xff1a;http://www.w3school.com.cn/cssref/pr_box-sizing.asp CSS3 box-sizing屬性&#xff1a; box-sizing: border-box; 抱歉&#xff0c;由于我的粗心&#xff0c;導致之前標題中的錯誤。目…

C語言編譯過程總結詳解

源文&#xff1a;http://bbs.dzsc.com/space/viewspacepost.aspx?postid76976 C語言的編譯鏈接過程要把我們編寫的一個c程序&#xff08;源代碼&#xff09;轉換成可以在硬件上運行的程序&#xff08;可執行代碼&#xff09;&#xff0c;需要進行編譯和鏈接。編譯就是把文本形…

DataFrame合并

獲取數據后&#xff0c;需要對數據進行合并&#xff0c;通常是日期&#xff0c;也有對相同公司進行合并 下面就研究數據合并的常用方法&#xff1a; 目錄 append merge concat 首先創建幾個DataFrame&#xff0c;作為樣本材料進行練習&#xff1a; df1 pd.DataFrame(np…

回顧小程序2018年三足鼎立歷程,2019年BAT火力全開

從 2018 年開年&#xff0c;小程序就成為了互聯網巨頭加緊布局的開始。微信小程序先發制人&#xff0c;且擁有 10 億月活躍用戶&#xff0c;如此巨大的流量往往使眾多后來者望而卻步。 但這里不包括阿里和百度。其實螞蟻金服團隊早在 2017 年 9 月便開始籌劃小程序&#xff0c;…

promise之我見

在我們平時的方法中有很多方法是promise封裝的&#xff0c; 有些函數后邊跟的then和catch 就是promise的方法&#xff0c;先看一下pormise的特點 &#xff08;1&#xff09;對象的狀態不受外界影響。Promise對象代表一個異步操作&#xff0c;有三種狀態&#xff1a;pending&…

2020-11-26

import datetime last[date] last[date].apply(lambda x:datetime.datetime.strptime(str(x),%Y%m%d).strftime(%Y/%m/%d)) cu.rename(columns{"Unnamed: 0":"date"},inplaceTrue) traindatapd.DataFrame(traindata,dtypenp.float) list 轉化Data Frame …

CPP虛析構函數

#include<iostream> using namespace std;class base {public:base(){};virtual ~base(){}; };// 在類聲明中聲明純虛析構函數 //base::~base() {}class father: public base {public:~father(){cout << "father" << endl;} };int main() {base* a…

學習過程中的一些想法

2019.01.18 問題描述&#xff1a;在學習響應式布局視頻教程的時候&#xff0c;遇到了一些不是特別明白的知識點&#xff0c;比如&#xff1a;媒體查詢、視口&#xff0c;視頻中會講解使用的那一部分東西&#xff0c;不太影響我繼續看視頻&#xff08;能大概理解&#xff09;&am…

idea 新建springboot 的 web 項目

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 IDAE中新建web項目見&#xff1a;IntelliJ IDEA中新建JAVA WEB項目、maven項目 默認已有一個 maven 的 web 項目&#xff1a;gentle --…

PHP工程師需要掌握的知識(轉載)

掌握PHP基礎、文件操作、面向對象編程、CURL擴展。掌握Linux環境下面LAMP環境搭建、LNMP環境搭建。了解基本的HTTP協議和計算機網絡知識。熟悉常用的算法與數據結構知識&#xff0c;隊列、棧、隊、圖、樹、排序算法等。熟悉前端HTML、CSS、jQuery、BootStarp等知識。熟悉常用的…

讀碼,解碼,轉換

import chardet f open(ff2.csv,rb) data f.read() chardet.detect(data){encoding: GB2312, confidence: 0.99, language: Chinese}

從全棧式解決方案到情感化,揭秘問眾智能切入車載語音市場的最佳姿勢...

*問眾智能CEO張亞 如果說語音交互是車載場景的最佳方式&#xff0c;未來誰掌握車內語音交互“話語權”&#xff0c;誰就將主宰車輛智能網聯的新時代。 經過多年的漸進式發展&#xff0c;語音交互的價值正逐步走出單純“控制方式”的狹隘理解&#xff0c;向業內人眼中的“智能…

浮想——我和CSDN走過了3個時代(長文,無耐心讀完者勿入)

上周末公司年會&#xff0c;董事長蔣濤同學分享了他13年的創業經歷。 算起來&#xff0c;這已經是我第1、2、3、4、5、6、7年參加CSDN的年會了。場面上&#xff0c;這也是最大的一次&#xff0c;也是蔣濤同學講話時間最長的一次。下午時光&#xff0c;寶貝正在我懷里沉沉的睡著…

CentOS7的yum安裝mysql

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、mariadb 查看CentOS7中是否已經安裝了mariadb數據庫,若安裝了mariadb數據庫&#xff0c;先卸載mariadb數據再安裝MySQL。若沒有安裝m…

3530: [Sdoi2014]數數

3530: [Sdoi2014]數數 鏈接 分析&#xff1a; 對給定的串建立AC自動機&#xff0c;然后數位dp。數位dp的過程中&#xff0c;記錄當前在AC自動機的哪個點上&#xff0c;保證不能走到出現了給定串的點。 代碼&#xff1a; #include<cstdio> #include<algorithm> #inc…