Scala 匿名函数是如何实现这个特性的?
让我们看看scala REPL中的代码: 首先,我定义了一个特征:Scala 匿名函数是如何实现这个特性的?,scala,traits,Scala,Traits,让我们看看scala REPL中的代码: 首先,我定义了一个特征: trait Service{ def invoke(name:String):String } 然后我定义了一个匿名函数: def serviceImpl:Service = (name)=> s"Your name is $name" 它很好用 serviceinpl方法返回一个匿名函数--“(name)=>s”您的名字是$name“”只是Function2[String,String]特征的一个实例 但是如上所
trait Service{
def invoke(name:String):String
}
然后我定义了一个匿名函数:
def serviceImpl:Service = (name)=> s"Your name is $name"
它很好用
serviceinpl
方法返回一个匿名函数--“(name)=>s”您的名字是$name“
”只是Function2[String,String]特征的一个实例
但是如上所述,匿名函数如何实现服务特性
scala是如何转换的?这是2.12发行说明中描述的一项新功能: Scala 2.12类型检查器接受函数文本作为任何单一抽象方法(SAM)类型的有效表达式,以及标准库中的FunctionN类型。这改善了使用Scala代码为Java8编写的库的体验。下面是一个使用java.lang.Runnable的REPL示例:
scala> val r: Runnable = () => println("Run!")
r: Runnable = $$Lambda$1073/754978432@7cf283e1
scala> r.run()
Run!
请注意,只有lambda表达式转换为SAM类型实例,而不是FunctionN类型的任意表达式:
scala> val f = () => println("Faster!")
scala> val fasterRunnable: Runnable = f
<console>:12: error: type mismatch;
found : () => Unit
required: Runnable
请注意,尽管这两种方法都适用,但重载解析会选择Function1参数类型的方法,如下所述。这是有效的,因为基于反射的duck类型与java lambda的约定相结合。提示:除非使用Scala 2.12.x,否则这不会很好地工作
public class A {
scala.Function1<String, String> f = s -> s.trim();
}
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