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.mzph.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…