匿名函数是如何实现 trait 的? [英] How did anonymous function implements the trait?

查看:43
本文介绍了匿名函数是如何实现 trait 的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们来看看scala REPL中的代码:首先,我定义了一个特征:

let's see the code in scala REPL: first, i defined a trait:

trait Service{
  def invoke(name:String):String
}

然后我定义了一个匿名函数:

then i defined an anonymous function:

def serviceImpl:Service = (name)=> s"Your name is $name"

效果很好.

serviceImpl 方法返回一个匿名函数 --- "(name)=> s"Your name is $name"" 只是 Function2[String, String] 特质.

the serviceImpl method returns an anonymous function --- "(name)=> s"Your name is $name"" is just an instance of Function2[String, String] trait.

但如上,匿名函数如何实现 Service trait?

but as above, how the anonymous function implements the Service trait?

scala 是如何转换的?

and How scala does this convert?

推荐答案

这是 2.12 发行说明中描述的新功能:http://www.scala-lang.org/news/2.12.0#lambda-syntax-for-sam-types

This is a new feature describe in the release notes of 2.12: http://www.scala-lang.org/news/2.12.0#lambda-syntax-for-sam-types

除了标准库中的 FunctionN 类型之外,Scala 2.12 类型检查器还接受函数文字作为任何单一抽象方法 (SAM) 类型的有效表达式.这改善了从 Scala 代码使用为 Java 8 编写的库的体验.这是一个使用 java.lang.Runnable 的 REPL 示例:

The Scala 2.12 type checker accepts a function literal as a valid expression for any Single Abstract Method (SAM) type, in addition to the FunctionN types from standard library. This improves the experience of using libraries written for Java 8 from Scala code. Here is a REPL example using java.lang.Runnable:

scala> val r: Runnable = () => println("Run!")
r: Runnable = $$Lambda$1073/754978432@7cf283e1
scala> r.run()
Run!

请注意,只有 lambda 表达式会转换为 SAM 类型实例,而不是 FunctionN 类型的任意表达式:

Note that only lambda expressions are converted to SAM type instances, not arbitrary expressions of FunctionN type:

scala> val f = () => println("Faster!")
scala> val fasterRunnable: Runnable = f
<console>:12: error: type mismatch;
found   : () => Unit
required: Runnable

语言规范包含 SAM 转换要求的完整列表.

The language specification has the full list of requirements for SAM conversion.

使用默认方法,Scala 的内置 FunctionN trait 被编译为 SAM 接口.这允许使用 Java 自己的 lambda 语法从 Java 创建 Scala 函数:

With the use of default methods, Scala’s built-in FunctionN traits are compiled to SAM interfaces. This allows creating Scala functions from Java using Java’s own lambda syntax:

public class A {
  scala.Function1<String, String> f = s -> s.trim();
}

专用函数类也是 SAM 接口,可以在包 scala.runtime.java8 中找到.

Specialized function classes are also SAM interfaces and can be found in the package scala.runtime.java8.

由于类型检查的改进,即使调用的方法重载,也可以省略 lambda 表达式中的参数类型.有关详细信息,请参阅 #5307.在以下示例中,编译器为 lambda 推断参数类型 Int:

Thanks to an improvement in type checking, the parameter type in a lambda expression can be omitted even when the invoked method is overloaded. See #5307 for details. In the following example, the compiler infers parameter type Int for the lambda:

scala> trait MyFun { def apply(x: Int): String }
scala> object T {
    |   def m(f: Int => String) = 0
    |   def m(f: MyFun) = 1
    | }
scala> T.m(x => x.toString)
res0: Int = 0

请注意,虽然这两种方法都适用,但重载解析会选择具有 Function1 参数类型的方法,如下文更详细的解释.

Note that though both methods are applicable, overloading resolution selects the one with the Function1 argument type, as explained in more detail below.

这篇关于匿名函数是如何实现 trait 的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆