Le suivant Scala fonctionne fonctionne et peut être transmis à un Java méthode s'attendant à une fonction. Y a-t-il un moyen plus propre de faire cela? Voici mon premier passage:
val plusOne = new Java.util.function.Function[Int,Int] {
override def apply(t:Int):Int = t + 1
override def andThen[V](after:function.Function[_ >: Int, _ <: V]):
function.Function[Int, V] = ???
override def compose[V](before:function.Function[_ >: V, _ <: Int]):
function.Function[V, Int] = ???
}
Voici mon deuxième passage - il utilise une enveloppe générique pour l'interface de fonction Java-8 pour rendre le Scala Syntax Syntax:
// Note: Function1 is Scala's functional interface,
// Function (without the 1) is Java 8's.
case class JavaFunction1[U,V](f:Function1[U,V]) extends Function[U,V] {
override def apply(t: U): V = f(t)
override def compose[T](before:Function[_ >: T, _ <: U]):
Function[T, V] = ???
override def andThen[W](after:Function[_ >: V, _ <: W]):
Function[U, W] = ???
}
val plusOne = JavaFunction1((x:Int) => x + 1)
val minusOne = JavaFunction1((x:Int) => x - 1)
Pouvons-nous faire mieux?
En suivant, y a-t-il une chance que Scala== sera un jour utiliser le code OP d'invoke-dynamique as Java 8 fait pour sa fonction de première classe Application? Cela fera-t-il que tout fonctionne comme par magie ou qu'il aura encore besoin d'être une conversion syntaxique?
Vous pouvez faire la conversion implicite:
implicit def toJavaFunction[U, V](f:Function1[U,V]): Function[U, V] = new Function[U, V] {
override def apply(t: U): V = f(t)
override def compose[T](before:Function[_ >: T, _ <: U]):
Function[T, V] = toJavaFunction(f.compose(x => before.apply(x)))
override def andThen[W](after:Function[_ >: V, _ <: W]):
Function[U, W] = toJavaFunction(f.andThen(x => after.apply(x)))
}
implicit def fromJavaFunction[U, V](f:Function[U,V]): Function1[U, V] = f.apply
Vous ne devriez pas avoir réellement besoin de remplacer compose
et andThen
, mais peut-être que le compilateur Scala ne connaît pas encore Java 8 méthodes d'interface par défaut. (Modifier: il devrait fonctionner dans la 2.10.3.)
De plus, vous devriez pouvoir affecter Scala lambdas (c.-à-d. x => ...
) à Function
et tout autre type SAM dans Scala 2.11 et Java 8 lambdas à Function1
. (Edit: Cela a été ajouté dans Scala 2.12, pas 2.11.)