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 ...
随机推荐
- 简易博客页面小项目 html css
项目预览 代码 html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- 强化学习调参技巧二:DDPG、TD3、SAC算法为例:
1.训练环境如何正确编写 强化学习里的 env.reset() env.step() 就是训练环境.其编写流程如下: 1.1 初始阶段: 先写一个简化版的训练环境.把任务难度降到最低,确保一定能正常训 ...
- Nmap扫描参数
执行Nmap/nmap --help查看帮助文档,将显示Namp的用法及其功能Nmap的相关参数的含义与用法:扫描目标时用到的参数:-iL:从文件中导入目标主机或目标网段-iR:随意选择目标主机--e ...
- dotTrace工具
1.dotTrace简介: (1)dotTrace是一个包含了可用于.NET应用程序的性能分析器(dotTrace Performance)和内存分析器(dotTrace Memory)的套件: (2 ...
- Windows下jdk安装与卸载-超详细的图文教程
jdk安装 下载jdk 由于现在主流就是jdk1.8,所以这里就下载jdk1.8进行演示.官方下载地址:https://www.oracle.com/java/technologies/downloa ...
- Hadoop详解(10) - Hadoop HA高可用
Hadoop详解(10) - Hadoop HA高可用 HA概述 HA(High Availablity),即高可用(7*24小时不中断服务). 实现高可用最关键的策略是消除单点故障.HA严格来说应该 ...
- C语言常用知识总结
在 C 语言中,常量是一种固定值的标识符,它的值在程序执行期间不会改变. C 语言中有几种不同类型的常量: 字符常量:用单引号括起来的单个字符,例如 'A'.'b'.'1' 等. 字符串常量:用双引号 ...
- Java基础篇——Gui编程
AWT 抽象窗口工具 组件:按钮(button) 文本域(textarea) 标签(label) 容器(container)... Frame窗口 Frame frame = new Frame( ...
- uniapp 开发微信小程序问题笔记
最近接手了一个小程序开发,从头开始.使用了 uniapp 搭建,以前没有做过小程序开发,着手看文档.查文档.一步一步完成了任务的开发.特此记录开发过程中的问题. 开发建议: 使用 HBuilderX ...
- DVWA靶场实战(十)——XSS(DOM)
DVWA靶场实战(十) 五.XSS(DOM): 1.漏洞原理: XSS全称为Cross Site Scripting,由于和层叠样式表(Cascading Style Sheets,CSS)重名,所以 ...