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,高阶函数)的更多相关文章

  1. kotlin学习(7)高阶函数

    高阶函数 以另一个函数作为参数或者返回值的函数被称为高阶函数. 函数类型 //隐式声明(省略了变量类型) val sum = (x:Int, y:Int -> x+y) val action = ...

  2. 匿名方法,Lambda表达式,高阶函数

    原文:匿名方法,Lambda表达式,高阶函数 匿名方法 c#2.0引入匿名方法,不必创建单独的方法,因此减少了所需的编码系统开销. 常用于将委托和匿名方法关联,例如1. 使用委托和方法关联: this ...

  3. Kotlin的高阶函数和常用高阶函数

    Kotlin的高阶函数和常用高阶函数 文章来源:企鹅号 - Android先生 高阶函数的定义 将函数当做参数或者是返回值的函数 什么是高阶函数 可以看看我们常用的 函数: 首先我们可以知道, 是 的 ...

  4. python学习-41 装饰器 -- 高阶函数

    装饰器:本质就是函数.是为其他函数添加附加功能的. 原则:1.不修改被修饰函数的源代码2.不修改被修饰函数的调用方式 --- 装饰器的知识储备 装饰器=高阶函数+函数嵌套+闭包 高阶函数 1.高阶函数 ...

  5. 『无为则无心』Python函数 — 33、高阶函数

    目录 1.高阶函数的定义 2.体验高阶函数 3.内置高阶函数 (1)map()函数 (2)reduce()函数 (3)filter()函数 1.高阶函数的定义 把函数作为参数传入(把一个函数作为另外一 ...

  6. javascript设计模式学习之三—闭包和高阶函数

    一.闭包 闭包某种程度上就是函数的内部函数,可以引用外部函数的局部变量.当外部函数退出后,如果内部函数依旧能被访问到,那么内部函数所引用的外部函数的局部变量就也没有消失,该局部变量的生存周期就被延续. ...

  7. Python 基础之匿名函数 迭代器和高阶函数

    一.匿名函数 lambda表达式 用一句话来表达只有返回值的函数,叫匿名函数特点:简洁方便语法:lambda 参数: 返回值 1.不带有参数的lambda表达式 def func():    retu ...

  8. python 把函数作为参数 ---高阶函数

    把函数作为参数 在2.1小节中,我们讲了高阶函数的概念,并编写了一个简单的高阶函数: def add(x, y, f): return f(x) + f(y) 如果传入abs作为参数f的值: add( ...

  9. 排序函数 sort() 和 高阶函数sorted()

    · sorted():该函数第一个参数iterable为任意可以迭代的对象,key是用于比较的关键字,reverse表示排序结果是否反转. · L.sort():该函数的三个参数和 sorted() ...

  10. Kotlin高阶函数实战

    前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...

随机推荐

  1. 常用内置模块之collections模块、时间模块、随机数random模块

    今日内容回顾 目录 今日内容回顾 包的具体使用 编程思想的转变 软件开发目录规范 常用内置模块之collections模块 常用内置模块之时间模块 常用内置模块之随机数random模块 报的具体使用 ...

  2. week_7

    Andrew Ng 机器学习笔记 ---By Orangestar Week_7 This week, you will be learning about the support vector ma ...

  3. Django框架:13、csrf跨站请求伪造、auth认证模块及相关用法

    Django框架 目录 Django框架 一.csrf跨站请求伪造 1.简介 2.csrf校验策略 form表单csrf策略 ajax请求csrf策略 3.csrf相关装饰器 FBV添加装饰器方式 C ...

  4. Less-1(GET字符型)

    union联合注入(方法一) 进入靶场 按照要求提交一个id:http://192.168.121.131/sqli/Less-1/?id=1 数据库执行语句:select * from news w ...

  5. s2-007

    漏洞名称 S2-007 CVE-2012-0838 远程代码执行 利用条件 Struts 2.0.0 - Struts 2.2.3 漏洞原理 age来自于用户输入,传递一个非整数给id导致错误,str ...

  6. SPOJ GCDMAT - GCD OF MATRIX

    简要题意 给出三个整数 \(T,n,m\),\(T\) 组询问,每组询问给出四个整数 \(i_1,j_1,i_2,j_2\)(数据保证 \(i_1,j_1\leq n\ \ i_2,j_2\leq m ...

  7. KingbaseES在线wal日志

    KingbaseES数据库日志文件记录数据库的历史操作信息, 包含恢复数据库中的所有事务所需的信息. KingbaseES在线WAL日志: WAL日志: 预写式日志(Write-Ahead Loggi ...

  8. 2.4.rpx单位有内置的视图容器组件

    所有的视图组件,包括view.swiper等,本身不显示任何可视化元素.它们的用途都是为了包裹其他真正显示的组件. # view 视图容器. 它类似于传统html中的div,用于包裹各种元素内容. 如 ...

  9. osx安装mpd和ncmpcpp

    简介 mdp 是一款开源的音乐播放软件, 全名为 media player daemon , 从字面意思理解, 就是一个后台播放进程. 不同于传统的音乐播放软件集成了播放解码和界面, mpd 只是一个 ...

  10. ClickHouse使用笔记

    什么是ClickHouse? ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS). 更多说明请参考官网:https://clickhouse.com/docs/zh/ ...