Kotlin学习笔记——(二)匿名函数、函数类型和lambda表达式

注:编码工具为IntelliJ

目录

匿名函数入门示例

函数类型和隐式返回

定义函数类型变量的两种方式

方式一:

方式二:

函数类型作为函数参数

非内联函数

内联函数

函数引用

函数类型作为函数的返回值


匿名函数入门示例

fun main() {
    val len = "KimuraTakuya".count { it == 'a' }
    println(len)
}

输出:

3

        示例中的{it == 'a'}就是一个匿名函数。

        匿名函数只有参数列表和函数体,没有函数名。

        匿名函数可以作为另一个函数的实际参数或者返回值。

        匿名函数==lambda表达式。

函数类型和隐式返回

        Kotlin中可以定义函数类型的变量,该变量可以作为函数使用,通过()或者invoke()调用。

        隐式返回:函数类型的实现即匿名函数中的返回值不能用return关键字修饰,函数体的最后一句的执行结果即为返回值。

package step_two

fun main() {
    // ()->Int 是函数类型
    // 等号后{}中的内容是函数的实现
    val f: ()->Int = {
        println("in Anonymous func")
        18
    }
    println(f())
    println(f.invoke())
}

输出:

in Anonymous func
18
in Anonymous func
18

定义函数类型变量的两种方式

方式一:

package step_two

fun main() {
    val func: (Int, Int) -> Int = {a, b -> a + b}
    println(func(12, 11))
}

输出:

23

方式二:

package step_two

fun main() {
    val func = { a: Int, b: Int -> a + b }
    println(func(12, 11))
}

输出:

23

        方式二,编译器会根据匿名函数体的最后一句执行结果推断返回值类型。

函数类型作为函数参数

        类似于Java中的回调接口。

非内联函数

        反编译为Java代码显示,将作为函数参数的函数定义成了一个对象,效率低。

package step_two

fun main() {
    login("abc", "123"){
        msg, code -> println("login result: msg = $msg, code = $code")
    }
}

fun login(user: String, pwd: String, result:(String, Int) -> Unit){
    if("abc" == user && "123" == pwd)
    {
        result("success", 200);
    }else{
        result("failure", 400);
    }
}

输出:

login result: msg = success, code = 200

反编译后的Java代码:

package step_two;

import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 5, 1},
   k = 2,
   d1 = {"\u0000\u001c\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\u0010\b\n\u0002\b\u0002\u001a0\u0010\u0000\u001a\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u00032\u0018\u0010\u0005\u001a\u0014\u0012\u0004\u0012\u00020\u0003\u0012\u0004\u0012\u00020\u0007\u0012\u0004\u0012\u00020\u00010\u0006\u001a\u0006\u0010\b\u001a\u00020\u0001¨\u0006\t"},
   d2 = {"login", "", "user", "", "pwd", "result", "Lkotlin/Function2;", "", "main", "kt"}
)
public final class FuncAsFuncParamKt {
   public static final void main() {
      login("abc", "123", (Function2)null.INSTANCE);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   public static final void login(@NotNull String user, @NotNull String pwd, @NotNull Function2 result) {
      Intrinsics.checkNotNullParameter(user, "user");
      Intrinsics.checkNotNullParameter(pwd, "pwd");
      Intrinsics.checkNotNullParameter(result, "result");
      if (Intrinsics.areEqual("abc", user) && Intrinsics.areEqual("123", pwd)) {
         result.invoke("success", 200);
      } else {
         result.invoke("failure", 400);
      }

   }
}

内联函数

        用inline关键字修饰的函数。当函数参数中含有函数时,将该函数定义为内联函数,反编译为Java代码后显示将内联函数的实现直接拷贝到了函数调用处,减少了函数的入栈出栈,效率高。

package step_two

fun main() {
    login("abc", "123"){
        msg, code -> println("login result: msg = $msg, code = $code")
    }
}

inline fun login(user: String, pwd: String, result:(String, Int) -> Unit){
    if("abc" == user && "123" == pwd)
    {
        result("success", 200);
    }else{
        result("failure", 400);
    }
}

输出:

login result: msg = success, code = 200

反编译后的Java代码:

package step_two;

import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 5, 1},
   k = 2,
   d1 = {"\u0000\u001c\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\u0010\b\n\u0002\b\u0002\u001a6\u0010\u0000\u001a\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u00032\u0018\u0010\u0005\u001a\u0014\u0012\u0004\u0012\u00020\u0003\u0012\u0004\u0012\u00020\u0007\u0012\u0004\u0012\u00020\u00010\u0006H\u0086\bø\u0001\u0000\u001a\u0006\u0010\b\u001a\u00020\u0001\u0082\u0002\u0007\n\u0005\b\u009920\u0001¨\u0006\t"},
   d2 = {"login", "", "user", "", "pwd", "result", "Lkotlin/Function2;", "", "main", "kt"}
)
public final class FuncAsFuncParamKt {
   public static final void main() {
      String user$iv = "abc";
      String pwd$iv = "123";
      int $i$f$login = false;
      short code;
      String msg;
      boolean var5;
      String var6;
      boolean var7;
      if (Intrinsics.areEqual("abc", user$iv) && Intrinsics.areEqual("123", pwd$iv)) {
         code = 200;
         msg = "success";
         var5 = false;
         var6 = "login result: msg = " + msg + ", code = " + code;
         var7 = false;
         System.out.println(var6);
      } else {
         code = 400;
         msg = "failure";
         var5 = false;
         var6 = "login result: msg = " + msg + ", code = " + code;
         var7 = false;
         System.out.println(var6);
      }

   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   public static final void login(@NotNull String user, @NotNull String pwd, @NotNull Function2 result) {
      int $i$f$login = 0;
      Intrinsics.checkNotNullParameter(user, "user");
      Intrinsics.checkNotNullParameter(pwd, "pwd");
      Intrinsics.checkNotNullParameter(result, "result");
      if (Intrinsics.areEqual("abc", user) && Intrinsics.areEqual("123", pwd)) {
         result.invoke("success", 200);
      } else {
         result.invoke("failure", 400);
      }

   }
}

函数引用

        用::函数名的形式,可以引用一个现有的符合条件的函数作为另一个函数实际参数。

package step_two

fun plus(a: Int, b: Int) {
    println("a + b = ${a + b}")
}

fun minus(a: Int, b: Int){
    println("a - b = ${a - b}")
}

fun calc(a: Int, b: Int, cal: (Int, Int) -> Unit) {
    cal(a, b)
}

fun main() {
    calc(99, 13, ::plus)
    val method = ::minus
    calc(10000, 1, method)
}

输出:

a + b = 112
a - b = 9999

函数类型作为函数的返回值

package step_two

fun main() {
    generateFunc("hello anonymous function")("this is another func")
}

fun generateFunc(msg: String): (String) -> Unit {
    println(msg)
    return { str: String -> println(str) }
}

输出:

hello anonymous function
this is another func

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值