美文网首页
2.3.6 -1.单个参数的隐式名称

2.3.6 -1.单个参数的隐式名称

作者: AndYMJ | 来源:发表于2021-07-06 23:13 被阅读0次

首先,也许你在it这个关键字上停留了好几秒,然后依旧不明其意。其实它也是Kotlin简化Lambda表达的一种语法糖,叫作 单个参数的隐式名称,代表了这个Lambda所接收的单个参数。这里的调用等价于:

listof(1,2,3).forEach{item -> foo(item)}

默认情况下,我们可以直接用it来代表item,而不需要item->进行声明。

其实,这行代码可能出乎你的预料,执行后你会发现什么也没有。为什么这样?这一次,我们必须要借助IDE的帮助了,以下是把foot函数用IDE转化后的Java代码

@JvmStatic

@Nullable

public static final Function0 foo(final int var0){

return (Function0)(new Function0(){

@Override

        public Object invoke() {

this.invoke();

return Unit.INSTANCE;

}

public final void invoke(){

int var1 =var0;

System.out.print(var1);

}

});

}

以上是字节码反编译的Java代码,从我们可以发现Kotlin实现Lambda表达式的机理。

2.Function类型

Kotlin在Jvm层设计了Function类型(Function0,Function1.......Function22)来兼容Java的Lambda表达式,其中的后缀数字代表了Lambda参数的数量,如以上的foo函数构建的其中是一个无参Lanbda,所以对应的接口是Function0,如果有一个参数那么对应的就是Function1。    它的源码中是如下定义的:

package kotlin.jvm.functions

interface Function1<in P1,out R>:Kotlin.Function<R>{

        fun invoke(p1:P1):R

}

可见每个Function类型都有一个invoke方法,稍后会详细介绍这个方法。

设计Function类型的主要目的之一就是要兼容Java,实现在Kotlin中也能调用Java的Lambda。在Java中,实际上并不支持把函数作为参数,而是通过函数式接口来实现这一特性。所以如果我们要把Java的Lambda传给Kotlin,那么它们就必须实现Kotlin的接口,在kotlin中我们则不需要跟它们打交道。在第6章我们会介绍如何在Kotlin中调用Java的函数式接口。

----------------

神奇的数字-22

也许你会有一个问题,:为什么这列Function类型最大的是Function22?如果Lambda的参数超过了22个,那该怎么办呢?

虽然22个参数已经够了,然而现实中也许我们真的需要超过22个参数。其实,在Scala的设计中也遵循了22个数字的设计,这似乎已经成为了业界的一种惯例。然而,这22的设计也给Scala开发者带来了不少麻烦。所以,Kotlin在设计的时候便考虑到了这种情况,除了23个常用的Function类型外,还有一个FunctionN。在参数真的超过22个的时候,我们就可以靠它来解决问题。更多的细节可以参考百度

--------------

3.invoke 方法

代码清单2-3中foo函数得返回值类型是Function0.这也意味着,如果我们调用了foo(n),那么实质上仅仅是构造了一个Function0对象。这个对象并不等价于我们要调用得过程本身。通过源码可以发现,需要调用Function0得invoke方法才能执行println方法。所以,我们的疑惑也一下解决了,上述的例子必须如下修改,才能够最终的打印我们想要的结果:

fun foo(int:Int) = {

print(int)

}

>>> listOf(1,2,3).forEach{foot(it).invoke()} //增加课invike调用

123

也许你觉得invke这种语法显得丑陋,不符合Kotlin简洁表达的设计理念。确实如此,所以我们还可以用熟悉的括号调用来代替invoke,如下所示:

>>>listOf(1,2,3).forEach{foo(it)()}

相关文章

  • 2.3.6 -1.单个参数的隐式名称

    首先,也许你在it这个关键字上停留了好几秒,然后依旧不明其意。其实它也是Kotlin简化Lambda表达的一种语法...

  • scala implicit 隐式转换和隐式参数

    1.什么是隐式转换和隐式参数?隐式转换是以implicit 声明的带有单个参数的函数隐式参数是函数或方法带有一个标...

  • Scala 隐式转换

    一、隐式转换 隐式转换需要执行隐式函数,隐式函数是以 implicit 关键字声明的带有单个参数的函数。隐式函数会...

  • 隐式转换

    隐式转换 隐式转换函数是以implicit关键字声明的带有单个参数的函数。这种函数将会自动应用,将值从一种类型转换...

  • 【Scala类型系统】隐式转换与隐式参数

    隐式转换 隐式转换是使用implicit修饰的带有单个参数的普通函数。这种函数将自动应用,将值从一种类型转换为另一...

  • 隐式转换

    1、隐式参数和隐式值 函数的形式参数如果用implicit修饰则是隐式参数,隐式参数可以有一个默认值,调用的时...

  • scala-隐式机制及Akka

    隐式机制及Akka 隐式转换 隐式转换和隐式参数时Scala中两个非常强大的功能,利用隐式转换和隐式参数,可以提供...

  • 第28课:Scala隐式转换内幕实践解密

    其实隐式转换有几种类型:隐式参数,隐式转换,隐式对象,和隐式类 首先看一下Scala的作用域 隐式参数冲突的情况:...

  • 函数显式参数(Parameters)与隐式参数(Argument

    看文档接触到了显示参数和隐式参数不懂,查了百度后给我搞的云里雾里这里我来给大家答疑解惑: 1. 显示参数和隐式参数...

  • Chapter 21《Implicit Conversions

    隐式转换和隐式参数 如果使用别人的代码库,无法进行修改,Scala进行扩展的方法是隐式转换和隐式参数。允许省略掉冗...

网友评论

      本文标题:2.3.6 -1.单个参数的隐式名称

      本文链接:https://www.haomeiwen.com/subject/llmnultx.html