Kotlin学习-函数(表达式,lambda,高阶函数)
Kotlin中函数 3种表达形式:
一般函数:
fun sum(a: Int, b: Int): Int {
return a+b
}
简化函数为表达式形式:
fun sum2(a: Int, b: Int): Int = a + b //函数表达式
fun max(a: Int, b: Int): Int = if(a > b) a else b //lambda函数
fun isOdd(x: Int) = x % 2 != 0
带默认参数的函数
//函数参数可以指定默认参数
fun multiply(a:Int,mut:Int=2):Int{
var result = 1
for(i in 0..mut){
result *= a
}
return result
}
lambda表达式函数定义:
1. 无参数情况 :
val/var 变量名 = { ... }
2. 有参数情况
val/var 变量名 : (参数的类型,参数类型,...) -> 返回值类型 = {参数1,参数2,... -> 操作参数的代码 }
示例:val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
注:(Int,Int)=>Int为函数签名,(a:Int,b:Int)表示函数参数
3,自动推导返回值类型(即表达式的返回值类型会根据代码实现块,推导出来)
val/var 变量名 = { 参数1 : 类型,参数2 : 类型, ... -> 操作参数的代码 }
示例:val sumLambda2 = {a : Int , b : Int -> a + b}
例如:
val sumLambda1: (Int, Int) -> Int = {x,y -> x+y}
val sumLambda2 = {a : Int , b : Int -> a + b}
高阶函数:apply/run/also/let/with
kotlin标准库提供了Any对象上下文内执行一段代码块,可用于对象初始化,直接使用对象内部方法,使代码更精简化。
run即可作用于Any,又可作为this代码块,run返回执行的是处理结果
fun getIdentify(index:Int):String{
val person_play = run {//将最后处理结果返回
when(index){
0 -> "manager"
1 -> "guest"
2 -> "worker"
else -> "none"
}
}
return person_play
} fun getSampleNickName(nn:String):String{
var sampleName = nn.run {
if(this.length>10)
substring(0,this.length-6)
else
nn
}
return sampleName
}
apply用法类似run,区别在于apply执行完成block()函数后,返回自身对象
返回自身对象,可以使用链式方法使用.apply{}.apply{}
val adam = Person("Adam").apply {
age = 20
city = "London"
}
fun testApply(st:String){
st.apply {
println("result:${this.plus("-java")}")
}.apply {
println("result:${this.plus("-php")}")
}
}
let内部使用it指代当前对象,返回最后一行处理结果, (T) -> R
fun testLet(st:String?){
st?.let { // execute this block if not nul
it.plus("-let1")
if(it.startsWith("android"))
it.drop(8)
} val listWithNulls: List<String?> = listOf("element1","element2", null)
for (item in listWithNulls) {
item?.let { // 元素不为空时执行
println(it)
}
}
}
与let函数相似,区别是also执行完成后返回对象本身,let返回处理结果
fun testAlso() {
val numberList = mutableListOf<Double>()
numberList.also {
println( "init the list")
}.also {
it.add( 2.71)
it.add(3.14)
it.add(1.0)
}.also {
println( "Sorting the list")
}.sort()
}
with函数作用于一个对象,返回最后一行处理结果
fun testWith(){
var p = Person("Tom", 26)
//写法一,对象receiver和一个lambda函数块
val result = with(p, {
println("my name is $name, I am $age years old")
1000
})
//由于with函数最后一个参数是一个函数,可以把函数提到圆括号的外部修改后
val result2 = with(p) {
println("my name is $name, I am $age years old")
1000
} val numbers = mutableListOf("one" , "two","three")
with(numbers) {
val firstItem = first()
val lastItem = last()
println("First item: $firstItem, last item:$lastItem")
}
}
其它高阶函数
fun fooLabel1() {
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return // local return to the caller of the anonymous fun, i.e. the forEach loop
print(value)
})
print(" done with anonymous function")
} fun fooLabel2() {
listOf(1, 2, 3, 4, 5).forEach lit1@{
if (it == 3) return@lit1 // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with explicit label")
}
fun fooLabel3() {//implicit label
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with implicit label")
} fun fooLabel5() {
run loop@{
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop // non-local return from the lambda passed to run
print(it)
}
}
print(" done with nested loop")
}
函数作为参数
在kotlin中函数可以作为参数传递给另一个函数去执行
例1:
var globalLock = ReentrantLock()
inline fun <T> lockInnerHandle(body: () -> T): T {//统一实现函数线程安全锁
globalLock.lock()
try {
return body()
}
finally {
globalLock.unlock()
}
}
通过这种方式可以统一实现某些功能的形式,简化函数重复代码量,高阶函数 run/apply/let/also等也是将函数作为参数处理的
例2:
//function as param
fun calFun(x:Int,y:Int,f:(Int,Int)->Int){
val result = f(x,y)
println(result)
}
//simple call
calFun(2,3,(a:Int,b:Int)=>{a*b})
函数引用
fun isOdd(x: Int) = x % 2 != 0
fun isOdd(s:String) = s =="kotlin"|| s =="java"|| s == "cpp"
fun calLength(s:String ) = s.length val numbers = listOf(1,2,3)
//normal invoke
println(numbers.filter { isOdd(it) })
//Function References ::调用
println(numbers.filter(::isOdd)) //组合函数使用
fun composeFun(){
val oddLength = compose(::isOdd, ::calLength)//compose(f, g) = f(g(*))
val strings = listOf("a","ab" , "abc" )
println(strings.filter(oddLength))
}
//组合函数定义
fun <A, B, C> compose(f: (B)-> C, g: (A) -> B): (A) -> C {
return { x -> f(g(x)) }
} //显示指定参数的方法,调用
val predicate: (String) -> Boolean = ::isOdd
predicate("cpp") //调用类成员
class A(val p:Int) //调用类的成员方法或扩展方法
val prop = A::p
Kotlin学习-函数(表达式,lambda,高阶函数)的更多相关文章
- kotlin学习(7)高阶函数
高阶函数 以另一个函数作为参数或者返回值的函数被称为高阶函数. 函数类型 //隐式声明(省略了变量类型) val sum = (x:Int, y:Int -> x+y) val action = ...
- 匿名方法,Lambda表达式,高阶函数
原文:匿名方法,Lambda表达式,高阶函数 匿名方法 c#2.0引入匿名方法,不必创建单独的方法,因此减少了所需的编码系统开销. 常用于将委托和匿名方法关联,例如1. 使用委托和方法关联: this ...
- Kotlin的高阶函数和常用高阶函数
Kotlin的高阶函数和常用高阶函数 文章来源:企鹅号 - Android先生 高阶函数的定义 将函数当做参数或者是返回值的函数 什么是高阶函数 可以看看我们常用的 函数: 首先我们可以知道, 是 的 ...
- python学习-41 装饰器 -- 高阶函数
装饰器:本质就是函数.是为其他函数添加附加功能的. 原则:1.不修改被修饰函数的源代码2.不修改被修饰函数的调用方式 --- 装饰器的知识储备 装饰器=高阶函数+函数嵌套+闭包 高阶函数 1.高阶函数 ...
- 『无为则无心』Python函数 — 33、高阶函数
目录 1.高阶函数的定义 2.体验高阶函数 3.内置高阶函数 (1)map()函数 (2)reduce()函数 (3)filter()函数 1.高阶函数的定义 把函数作为参数传入(把一个函数作为另外一 ...
- javascript设计模式学习之三—闭包和高阶函数
一.闭包 闭包某种程度上就是函数的内部函数,可以引用外部函数的局部变量.当外部函数退出后,如果内部函数依旧能被访问到,那么内部函数所引用的外部函数的局部变量就也没有消失,该局部变量的生存周期就被延续. ...
- Python 基础之匿名函数 迭代器和高阶函数
一.匿名函数 lambda表达式 用一句话来表达只有返回值的函数,叫匿名函数特点:简洁方便语法:lambda 参数: 返回值 1.不带有参数的lambda表达式 def func(): retu ...
- python 把函数作为参数 ---高阶函数
把函数作为参数 在2.1小节中,我们讲了高阶函数的概念,并编写了一个简单的高阶函数: def add(x, y, f): return f(x) + f(y) 如果传入abs作为参数f的值: add( ...
- 排序函数 sort() 和 高阶函数sorted()
· sorted():该函数第一个参数iterable为任意可以迭代的对象,key是用于比较的关键字,reverse表示排序结果是否反转. · L.sort():该函数的三个参数和 sorted() ...
- Kotlin高阶函数实战
前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...
随机推荐
- war包形式安装jenkins
(1)下载war包 输入命令:java -jar jenkins.war --httpPort=8080,更改端口 重新登录之后,输入密码创建用户等完成设置 (2)结合Tomcat安装: 将jenki ...
- JavaScript:代码细节和良好编码习惯
这些细节,与语法无关,仅仅是编写代码时需要注意的最最基本的细节和一些良好编码习惯. 注释代码 注释代码分为单行注释和多行注释,如下所示: 严格区分大小写 JS的代码时严格区分大小写的,变量a和A是不同 ...
- 数值计算:前向和反向自动微分(Python实现)
1 自动微分 我们在<数值分析>课程中已经学过许多经典的数值微分方法.许多经典的数值微分算法非常快,因为它们只需要计算差商.然而,他们的主要缺点在于他们是数值的,这意味着有限的算术精度和不 ...
- Kali Win-KeX Win
内容: 概述 用法 开始 启动根会话 会话管理 声音支持 多屏支持 停止 概述 窗口模式下的 Win-KeX 将在单独的窗口中运行 Kali Linux 桌面会话. 窗口模式有助于在视觉上将 Wind ...
- [C++]std::sort()函数使用总结
函数声明 template< class RandomIt, class Compare > constexpr void sort( RandomIt first, RandomIt l ...
- 数论专项复习(一)扩展欧几里得算法(exgcd)
简介 扩展欧几里得算法(简称扩欧,exgcd),用来求下列方程的一组解: \[ax+by=(a,b) \] 算法介绍 1. 裴蜀定理 裴蜀定理(Bézout's lemma):若 \(a\in \ma ...
- CF1779C Least Prefix Sum 题解
CF链接:Least Prefix Sum Luogu链接:Least Prefix Sum $ {\scr \color {CornflowerBlue}{\text{Solution}}} $ 先 ...
- 分布式协议与算法-Raft算法
本文总结自:极客时间韩健老师的分布式协议与算法实战课程. 大家都知道,Raft算法属于Multi-Paxos算法,它是在Multi-Paxos思想的基础上,做了一些简化和限制.关于Paxos算法,博主 ...
- Python 内置界面开发框架 Tkinter入门篇 丙(文末有福利彩蛋,今天可是元宵节)
以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/B1hH5Qzd2RkAiiUId1tLWw 本文大概 2874 个字 ...
- Python装饰器实例讲解(三)
Python装饰器实例讲解(三) 本文多参考<流畅的python>,在此基础上增加了一些实例便于理解 姊妹篇 Python装饰器实例讲解(一),让你简单的会用 Python装饰器实例讲解( ...