【问题标题】:Scala single method interface implementationScala单方法接口实现
【发布时间】:2014-04-02 18:46:27
【问题描述】:
【问题讨论】:
-
我有一个基于概念验证的小演示 here。它可以很容易地变得更通用和更健壮,但你不会得到你所要求的简洁性。
标签:
scala
interface
lambda
syntactic-sugar
traits
【解决方案1】:
Scala 从 2.11 开始对 SAM 提供实验性支持,标记为 -Xexperimental:
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
预期类型的通常限制也适用:
- 它必须定义一个抽象方法,
- 其主要构造函数(如果有)必须是公共的、无参数的、未重载的,
- 抽象方法必须采用单个参数列表,
- 抽象方法必须是单态的。
根据 Adriaan 的 original commit,未来可能会取消其中一些限制,尤其是最后两个。
【解决方案2】:
使用 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")
}
【解决方案3】:
虽然以通用方式执行此操作肯定很复杂,但如果您发现您确实只需要对少数特定 Java 类型执行此操作,那么一些简单的隐式转换就可以很好地完成这项工作。例如:
val thread = new Thread(() => println("hello world"))
thread.start
implicit def function0ToRunnable(f:() => Unit):Runnable =
new Runnable{def run() = f()}
如果您的实际问题比您想象的更有限,有时尝试以通用且完全可重用的方式解决问题是错误的方法。