日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Kotlin 学习笔记08

發(fā)布時(shí)間:2023/12/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kotlin 学习笔记08 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Lambda作為形參和返回值

聲明高階函數(shù)

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

{ x, y -> x + y} 這里省略了參數(shù)x,y類型,因?yàn)樵谄渌糠忠呀?jīng)制定了,不需要在lambda函數(shù)體再次聲明

val funOrNull: ((Int, Int) -> Int)? = null 復(fù)制代碼
  • 可以為函數(shù)參數(shù)制定名字
//聲明 fun performRequest(url: String,callback: (code: Int, content: String) -> Unit ){} //調(diào)用 val url = "http://baidu.com" performRequest(url,{code, content -> /*code*/ }) performRequest(url){code, content -> /*code*/ }//根據(jù)kotlin約定,lambda為最后一個(gè)參數(shù),可以放到括號(hào)外面 復(fù)制代碼
  • 調(diào)用函數(shù)
//聲明一個(gè)函數(shù),參數(shù)為一個(gè)函數(shù),這個(gè)函數(shù)有2個(gè)參數(shù)都是int值,返回值也為int fun towAndThree(operator: (x: Int, y: Int) -> Int) {//這里的x,y是可以省略的,省略了,IDE代碼補(bǔ)全會(huì)不方便val result = operator(3, 4)print("the result is $result") } 復(fù)制代碼
  • filter()函數(shù)
//聲明 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 } //調(diào)用 println(url.filter { it in 'a'..'z' }) 復(fù)制代碼

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

函數(shù)類型的參數(shù)默認(rèn)值和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() } 復(fù)制代碼

返回函數(shù)的函數(shù)

  • 比如運(yùn)輸費(fèi)用依賴于運(yùn)輸方式,可以定義一個(gè)函數(shù),用來(lái)選擇恰當(dāng)?shù)倪壿嬜凅w,并將它作為一個(gè)函數(shù)返回
fun getShoppingCarCacul(delivery: Delivery): (Order) -> Double {if (delivery == Delivery.STANDARD) {return { order: Order -> 6 + 2.1 * order.itemCont }}return { order -> 1.2 * order.itemCont } } //調(diào)用 var shoppingCarCacul = getShoppingCarCacul(Delivery.EXPEDITED) println("產(chǎn)生的運(yùn)費(fèi):${shoppingCarCacul(Order(4))}") 復(fù)制代碼
  • eg:通過(guò)輸入開(kāi)頭文字,過(guò)濾聯(lián)系人列表
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,因?yàn)镮DE推斷不出it代表是什么if (!isOnlyPhoneNumber) {return startWithPrefix}return { man: Man -> startWithPrefix(man) && man.phoneNumber != null }//這里可以是用it,這里是根據(jù)方法的返回值類型,推斷出it代碼得man} } //調(diào)用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())) 復(fù)制代碼

使用lambda去除重復(fù)代碼

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()//調(diào)用 println(log.averageTime(OS.WINDOWS)) 復(fù)制代碼
  • 如果說(shuō)要查詢WINDOW、和Android的呢?后面又需要改成來(lái)自iOS的注冊(cè)頁(yè)面停留時(shí)間是多少呢?這個(gè)時(shí)候lambda就派上用場(chǎng)了。
fun List<SiteVisit>.averageTime(predicate: (SiteVisit) -> Boolean) = filter(predicate)//這里的篩選改為lambda。.map { it.duration }.average() 復(fù)制代碼

把過(guò)濾條件轉(zhuǎn)換成lambda表達(dá)式,實(shí)現(xiàn)去除重復(fù)代碼
策略模式(你需要聲明一個(gè)接口,并且為每一種可能實(shí)現(xiàn)不同的策略)可以通過(guò)lambda簡(jiǎn)化

內(nèi)聯(lián)函數(shù):消除lambda運(yùn)行時(shí)帶來(lái)的開(kāi)銷

在kotlin中,每創(chuàng)建一個(gè)lambda表達(dá)式就會(huì)創(chuàng)建一個(gè)匿名類,so,每次調(diào)用都會(huì)創(chuàng)建一個(gè)對(duì)象,會(huì)帶來(lái)額外的開(kāi)銷這個(gè)時(shí)候inline就出現(xiàn)了。
一個(gè)被inline修飾的函數(shù),函數(shù)體會(huì)直接替換到函數(shù)被調(diào)用的地方,而不是正常調(diào)用。一般來(lái)說(shuō),參數(shù)如果被直接調(diào)用或者作為參數(shù)傳遞給另外一個(gè)inline函數(shù)。他是可以被內(nèi)聯(lián)的。

  • 內(nèi)聯(lián)函數(shù)使用限制-》不能把內(nèi)聯(lián)函數(shù)保存到一個(gè)屬性?

內(nèi)聯(lián)集合操作

Kotlin標(biāo)準(zhǔn)庫(kù)中,集合函數(shù),比如filter,map等函數(shù)已經(jīng)inline函數(shù),不會(huì)產(chǎn)生額外的對(duì)象。在處理比較大的集合,應(yīng)該使用序列asSequence進(jìn)行操作。

怎樣決定是否使用lambda

  • 使用inline關(guān)鍵字只能提高帶有l(wèi)ambda參數(shù)的函數(shù)的性能。
  • 對(duì)于普通函數(shù)JVM已經(jīng)提供了強(qiáng)大的內(nèi)聯(lián)支持。
  • 應(yīng)該保證inline修飾的函數(shù)比較小。-》因?yàn)樾枰押瘮?shù)字節(jié)碼拷貝到每一個(gè)調(diào)用點(diǎn)上。

使用lambda管理資源

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

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

在Kotlin中使用use實(shí)現(xiàn)相同的結(jié)果,用于操作可關(guān)閉的資源。

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

高階函數(shù)中的控制流

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

同樣的規(guī)則也適用于this表達(dá)式

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

在filter中使用匿名函數(shù)

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

如果是使用表達(dá)式函數(shù)體,可以省略返回值類型,可以簡(jiǎn)化為

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

End

轉(zhuǎn)載于:https://juejin.im/post/5c3d728af265da61171cf3c3

總結(jié)

以上是生活随笔為你收集整理的Kotlin 学习笔记08的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。