Scala单方法接口实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala单方法接口实现相关的知识,希望对你有一定的参考价值。
Scala是否有任何语法糖来替换以下代码:
val thread = new Thread(new Runnable {
def run() {
println("hello world")
}
})
更喜欢的东西:
val thread = new Thread(() => println("hello world"))
在特征/接口只需要实现一种方法的情况下?如果没有,将来是否有机会在Scala中使用此功能?当处理Java类时,它特别有用。
三年前我发现了一个类似的问题:Generically implementing a Java Single-Abstract-Method interface with a Scala closure?答案说我们应该在Scala 2.10中有这个功能。我找了单一抽象方法关键字,但我没有找到任何东西。这个功能发生了什么?
答案
Scala在标准-Xexperimental
下以2.11开始实验性支持SAMs:
Welcome to Scala version 2.11.0-RC3 (OpenJDK 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :set -Xexperimental
scala> val r: Runnable = () => println("hello world")
r: Runnable = $anonfun$1@7861ff33
scala> new Thread(r).run
hello world
编辑:从2.11.5开始,这也可以内联完成:
scala> new Thread(() => println("hello world")).run
hello world
关于预期类型的通常限制也适用:
- 它必须定义一个抽象方法,
- 它的主要构造函数(如果有的话)必须是public,no-args,not overloaded,
- 抽象方法必须采用单个参数列表,
- 抽象方法必须是单形的。
根据Adriaan的original commit,未来可能会取消其中一些限制,特别是最后两个。
另一答案
虽然以通用方式执行此操作当然很复杂,但如果您发现实际上只需要一些特定的Java类型,那么一些简单的隐式转换可以很好地完成这项工作。例如:
val thread = new Thread(() => println("hello world"))
thread.start
implicit def function0ToRunnable(f:() => Unit):Runnable =
new Runnable{def run() = f()}
如果您的实际问题比您想象的更有限,有时尝试以通用且完全可重复使用的方式解决问题是错误的方法。
另一答案
使用invokeDynamic支持SAM类型,因为scala-2.12类似于JDK-8,下面是在2.12.3上测试的 - 关于SAM的发行说明可以在这里找到 - http://www.scala-lang.org/news/2.12.0/
object ThreadApp extends App {
println("Main thread - begins")
val runnable: Runnable = () => println("hello world - from first thread")
val thread = new Thread(runnable)
println("Main thread - spins first thread")
thread.start()
val thread2 = new Thread(() => println("hello world - from second thread"))
println("Main thread - spins second thread")
thread2.start
thread.join()
thread2.join()
println("Main thread - end")
}
以上是关于Scala单方法接口实现的主要内容,如果未能解决你的问题,请参考以下文章