-
什么是匿名函数
- 没有名字的;直接就给出了函数体
-
account的使用
- count{},包裹的部分就是匿名函数(这个匿名函数就只有一条语句:it == 'r')
fun main(){ val len = "WAsbry".count() println(len)//6 val len1 = "WAsbry".count{ //it等于W A s b r y中的每一个字符 it == 'r'//这一句就是匿名函数 } println(len1)//出来1 } -
Kotlin函数拆解与隐式返回
-
概述:
- 函数拆解:将一个完整的函数定义拆成声明与实现两个部分
- 隐式返回:Kotlin中的匿名函数的最后一行就是其返回值
-
用处:可以在函数A中定义函数B
-
拆解步骤
- 定义函数的输入输出声明
- 定义函数的实现
-
细节:
- 匿名函数的返回值在声明处就已经定义好了
- 匿名函数中不要写return语句,匿名函数的最后一行就是其返回值
fun main(){ //定义函数输入输出的声明 :表示后接函数输入/出 ()为函数输入 -> 为函数输出 val methodAction : () -> String //第二步:对函数的实现 methodAction = { val inputValue = 999 "$inputValue WAsbry" //88,这样子就要报错,因为kotlin中的匿名函数的最后一行就是此函数的返回值(并且在函数声明的时候就指定了这个匿名函数的返回值是String)--->会造成类型对不上 } //第三步:调用此函数 println(methodAction())//打印出999 WAsbry } -
-
Kotlin 函数参数进阶版本
-
概述:
- 在函数声明的时候,指定形参类型(可以不要具体变量),指定返回值,将声明与实现使用=进行连接
- 在函数实现体(匿名函数)中指定具体变量用于承接函数参数
- 匿名函数的最后一行为其返回值,不要在匿名函数中写return语句
fun main(){ //函数声明与实现 val methodAction : (Int,Int,Int) -> String={number1,number2,number3 -> val inputValue=999 "$inputValue Wasbry 参数一:$number1,参数二:$number2,参数三:$number3" } //函数的调用 println(methodAction(1,2,3)) } //上面的那个(除了函数调用)等效于下面这个 fun methodAction(number1: Int,number2: Int,number3:Int): String{ val inputValue = 999 return "$inputValue WAsbry 参数一:$number1,参数二:$number2,参数三:$number3" } -
-
it 关键字
-
场景
- 当函数只有一个参数的时候,kotlin会在函数体中内置一个it,作为这个参数的指代
-
实现细节
- 当函数形参是Double,实参也要是Double,不能传int值;
- 在这个kotlin 里面好像没得关于函数参数的自动类型转化
- 有两个及以上的函数参数就没有 it 了
fun main(){ //对于这种只有一个参数的匿名函数来说,仅需指定形参类型不需要搞一个具体形参属性 val methodAction2 : (String) -> String = {"$it WAsbry"}//函数的声明与实现 //函数的调用,打印它的返回值 println(methodAction2("parm"))//打印出:parm WAsbry } //跟上面那个等价,这个it是被隐藏了的 fun methodAction2(it: String) : String{return "$it WAsbry"} -
-
匿名函数的类型推断
-
概述:匿名函数的返回值是不用显示指明的(可以自动推断的)
-
实现细节
-
当函数名后接冒号,必须制定参数类型与返回类型
fun main(){ val method1 : (String)->String = {} } -
当函数名后接等号,函数体(匿名函数中)最后一行就是函数的返回值
-
不用显示指定函数参数类型
//不指定函数参数类型,此时函数的返回值为浮点数 fun main(){ val method3 = { 345.3f } } -
不用显示指定函数返回值类型
fun main(){ //这三个是传入的参数 val method2 = {v1:Double,v2:Float,v3:Int -> 555//作为匿名函数的最后一行,那么这个函数的返回值就是Int ""//作为匿名函数的最后一行,此时函数的返回值类型为String true//Boolean 3.14f//Float } //匿名函数调用 println(method2(3.14,2.68f,666)) }
-
-
-
-
Lamda学习
-
概述:
- 括号就是一个匿名函数
- 匿名函数就是lamda,他们是等价的,只是名字不一样而已
-
实现两数相加
fun main(){ val addResultMethod = {number1: Int,number2: Int -> "两数相加的结果是:${number1 + number2}" } } -
匿名函数的返回值类型(多种返回值类型可能--->就返回Any类型)
fun main(){ //匿名函数 入参Int, 返回类型Any(因为有可能有多种返回值类型) //Lamda表达式的参数Int, Lamda表达式的结果为Any类型 val weekResultMethod = { number: Int when(number){ 1 -> "星期一" 2 -> "星期二" 3 -> "星期三" else -> -1 }//注意,这个when整体算作一条语句,在匿名函数中默认使用函数体内最后一条语句作为函数的返回值 } println(weekResultMethod(2))//打印出"星期二" }
-
-
函数作为函数参数
-
概述:
- Java中使用接口
- Kotlin 直接哪一个Lamda作为函数的参数,进行处理
-
应用
- 模拟数据库登录
-
-
-
实现细节
-
在java中作值判断,采用equals,但是在kotlin中可以直接采用 ==
-
java 中的 if 是一条语句,而kotlin中的 if 是一个表达式(具有返回值)
-
kotlin中的字符串模板,可以作为java中的String.format(Kotlin 中的字符串模板)
-
在kotlin中同一个package下的类中都不能有重名的方法
- 在查看kotlin的java版本的时候发现,kotlin中的函数在转换为java的方法的时候,会在前面加上public static void
-
- 代码示例(kotlin版本)
```
/**
* 使用Lamda表达式作为函数参数,可以写在函数参数列表里面,也可以写在外面;
* */
fun main(){
//第一种实现方式,函数原型的参数三是一个Lamda(匿名函数),
loginAPI("WAsbry","1008611",{msg: String,code: Int ->
println("最终登录的情况如下:msg:$msg,code:$code")
})
//第二种实现方式
loginAPI("WAsbry","1008611",responseResult = {msg: String,code:Int ->
println("最终登录的情况如下:msg:$msg,code:$code")
})
//第三种实现方式
loginAPI("WAsbry","1008611"){msg: String,code:Int ->
println("最终登录的情况如下:msg:$msg,code:$code")
}
}
//模拟数据库SQLSever
const val USER_NAME_SAVE_DB="WAsbry";
const val USER_PWD_SAVE_DB="1008611";
//登录API,模仿前端操作
//采用Lamda表达式:responseResult:(String,Int)->Unit来代替接口
fun loginAPI(username: String,userpassword: String,responseResult: (String,Int)->Unit){
if(username == null || userpassword == null){
TODO("用户名或者密码为空")//程序发现异常,终止
}
//做校验工作,前段校验
if(username.length>3 && userpassword.length>3){
if (webServiceLoginAPI(username,userpassword)){
//登录成功
//可以做一些其他的事情,比如说校验成功信息等
responseResult("login success",200)
}else{
//登录失败的逻辑处理
responseResult("login error",444)
}
}else{
TODO("用户名或密码不规范,请检查输入")
}
}
//登录API暴露者,服务器
private fun webServiceLoginAPI(name: String,pwd: String):Boolean{
//Kotlin中的 if 是表达式,这玩意儿是可以有返回值的
return if(name==USER_NAME_SAVE_DB && pwd==USER_PWD_SAVE_DB) true else false
}
```
- 代码示例(java版本)
```
package Kotlin;
interface ResponseResult{
void result(String msg,int code);
}
public class Test {
public static final String USER_NAME_SAVE_DB="WAsbry";
public static final String USER_PWD_SAVE_DB = "1008611";
public static void main(String[] args) {
//第一种实现方式,函数原型的参数三是一个Lamda(匿名函数),
loginAPI("WAsbry", "1008611", new ResponseResult() {
@Override
public void result(String msg, int code) {
System.out.println(String.format("最终登录的情况如下:msg:%s,code:%d",msg,code));
}
});
}
public static void loginAPI(String username,String userpassword,ResponseResult responseResult){
if(username == null || userpassword == null){
// TODO("用户名或者密码为空")//程序发现异常,终止
}
//做校验工作,前段校验
if(username.length()>3 && userpassword.length()>3){
if (webServiceLoginAPI(username,userpassword)){
//登录成功
//可以做一些其他的事情,比如说校验成功信息等
responseResult.result("login success",200);
}else{
//登录失败的逻辑处理
responseResult.result("login error",444);
}
}else{
// TODO("用户名或密码不规范,请检查输入")
}
}
//登录API暴露者,服务器
private static boolean webServiceLoginAPI(String name,String pwd){
//Kotlin中的 if 是表达式,这玩意儿是可以有返回值的
if(name==USER_NAME_SAVE_DB && pwd==USER_PWD_SAVE_DB)
return true;
else
return false;
}
}
```
-
简化版本
-
概述:Lamda 表达式可以写在外面也可以写在里面
//第一种实现方式,函数原型的参数三是一个Lamda(匿名函数), loginAPI("WAsbry","1008611",{msg: String,code: Int -> println("最终登录的情况如下:msg:$msg,code:$code") }) //第二种实现方式 loginAPI("WAsbry","1008611",responseResult = {msg: String,code:Int -> println("最终登录的情况如下:msg:$msg,code:$code") }) //第三种实现方式 loginAPI("WAsbry","1008611"){msg: String,code:Int -> println("最终登录的情况如下:msg:$msg,code:$code") }
-
-
Kotlin中的内联
- 当函数参数含有Lamda项,尽量在函数前面使用inline关键词,这样做,会在调用处做代码替换处理,类似于C++中的宏定义;进而减少函数开辟,对象开辟,函数调用,对象调用
import webServiceLoginAPI as webServiceLoginAPI1 /** * 使用Lamda表达式作为函数参数 * */ fun main(){ loginAPI("WAsbry","1008611"){msg: String,code:Int -> println("最终登录的情况如下:msg:$msg,code:$code") } } //模拟数据库SQLSever const val USER_NAME_SAVE_DB="WAsbry"; const val USER_PWD_SAVE_DB="1008611"; //采用Lamda表达式来代替接口 //此函数中有Lamda参数,使用内联, //如果说,不适用内联,在调用端会生成多个对象来完成Lamda的调用(造成性能损耗),这个在字节码里面就能看到 //内联类似于C++中的define,编译期间将代码替换到调用处,那么在调用出原始的对象创建,调用等都没得了,快 inline fun loginAPI(username: String,userpassword: String,responseResult: (String,Int)->Unit){ if(username == null || userpassword == null){ TODO("用户名或者密码为空")//程序发现异常,终止 } //做校验工作,前段校验 if(username.length>3 && userpassword.length>3){ if (webServiceLoginAPI1(username,userpassword) ){ //登录成功 //校验成功 responseResult("login success",200) }else{ //登录失败的逻辑处理 responseResult("login error",444) } }else{ TODO("用户名或密码不规范,请检查输入") } } //次函数没有使用Lamda作为参数,那么久不要声明为内联 //登录API暴露者,服务器 private fun webServiceLoginAPI(name: String,pwd: String):Boolean{ //Kotlin中的 if 是表达式,这玩意儿是可以有返回值的 return if(name==USER_NAME_SAVE_DB && pwd==USER_PWD_SAVE_DB) true else false } -
Kotlin 中的函数引用
-
概述:
- Lamda是函数类型的对象
- 内联 (inline,配合 :: 进行使用)就可以将一个普通函数变成函数类型的对象
- 函数引用可以将函数作为一个参数进行传入
-
应用场景:
- 函数A参数为Lamda表达式,
-
使用方法:
- 将Lamda表达式的实现抽象为一个函数B
- 在函数A前,加上内联符号inline
- 在调用函数A的时候,将参数Lamda,使用 ::B 进行替换
-
好处:
- 提升性能
-
实现细节:
- 也可以将函数引用封装为一个变量,作为函数参数
-
代码示例:
/** * 使用Lamda表达式作为函数参数 * */ fun main(){ //函数引用,第三个为函数对象,将普通类型变成函数引用,Lamda的调用 login("WAsbry","1008611",::methodResponseResult) val obj=::methodResponseResult val obj2=obj val obj3=obj2 //这样子也是可以调用的 login("WAsbry","1008611",obj3) } //Lamda的实现 fun methodResponseResult(msg: String,code: Int){ println("最终登录结果:msg:$msg,code:$code") } //模拟数据库SQLSever const val USER_NAME_SAVE_DB="WAsbry"; const val USER_PWD_SAVE_DB="1008611"; //这里的第三个参数是Lamda的声明 inline fun login(name: String,pwd: String,responseResult: (String,Int)->Unit){ if (USER_NAME_SAVE_DB == name && USER_PWD_SAVE_DB == pwd){ //登录成功,书写相应的逻辑 responseResult("登陆成功",200) }else{ //登录失败,书写相应的逻辑 responseResult("登录失败",404) } } -
-
函数类型作为返回类型(在函数中返回一个函数)
-
概述:
- 匿名函数B作为函数A的返回类型
- Java是做不到的
-
实现细节:
- 需要在函数的声明处指定好匿名函数的规则
fun main(){ show("Hello World") val fake_show=showMethod("fake") //这里就证明了,第三行的返回值是一个函数,因为这个返回值是可以调用的 fake_show("WAsbry",20)//打印出 我就是匿名函数:我的name:WAsbry,age:20 } fun show(info: String):Boolean{ println("这里是show函数,info:$info") return true } fun show2(info: String):String{ println("这里是show函数") return "DDD" } //14行,显示指明了这个函数是返回一个函数类型的变量,入参是String,Int,返回值为String fun showMethod(info: String):(String,Int)->String{ println("这是show函数 info:$info") //return 一个匿名函数 return { name:String,age:Int-> "我就是匿名函数:我的name:$name,age:$age" } } -
-
Kotlin 中的具名函数
- Lamda是函数对象级别的,对照着函数引用,普通的函数需要转成函数引用才能匹配
//lamda表达式的本质是函数对象级别的,那么需要将普通函数转变为函数对象级别的才能去对标Lamda fun main(){ //匿名函数 showPersonInfo("lisi",99,'男',"Hello Kotlin"){ println("显示结果:$it") }//这括号及其里面的代码就是匿名函数,也叫Lamda的实现体 //具名函数showResultIml showPersonInfo("wang",99,'女',"Hello Java",::showResultIml) } fun showResultIml(result: String){ println("显示结果:$result") } inline fun showPersonInfo(name:String,age:Int,sex:Char,study:String,showResult:(String)->Unit){ val str="name:$name,age:$age,sex:$sex,study:$study" showResult(str) }java版本:需要使用接口的这种折中的方案来实现kotlin中的Lamda表达式效果
package Kotlin; interface IsShowResult{ void result(String result); } public class Test { public static void main(String[] args) { //匿名函数 -> 匿名接口实现 showPersonInfo("lisi", 99, 'm', "study kotlin", new IsShowResult() { @Override public void result(String result) { System.out.println("显示结果: "+result); } }); //具名函数 具名接口实现showResultIml IsShowResult showResultIml = new MshowResultIml(); showPersonInfo("wangwu",88,'n',"study kotlin",showResultIml); } static class MshowResultIml implements IsShowResult{ @Override public void result(String result) { } } static void showPersonInfo (String name,int age,char sex,String study,IsShowResult isShowResult) { String str= String.format("name:$name,age:$age,sex:$sex,study:$study"); isShowResult.result(str); } }