Scala işlevinin Java 8 yöntemine geçirilmesi


18

Aşağıdaki Scala kodu çalışır ve bir işlev bekleyen bir Java yöntemine geçirilebilir. Bunu yapmanın daha temiz bir yolu var mı? İşte ilk geçişim:

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] = ???
}

İşte benim ikinci geçişim - Scala sözdizimini daha basit hale getirmek için Java-8 Function arayüzü için genel bir sarmalayıcı kullanıyor:

// 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)

Daha iyisini yapabilir miyiz?

Bir takip olarak, Scala'nın Java 8'in birinci sınıf fonksiyon uygulaması için yaptığı gibi bir gün invoke-dinamik op-kodunu kullanma şansı var mı? Bu her şeyi sihirli bir şekilde çalıştıracak mı, yoksa yine de sözdizimsel bir dönüşüm olması gerekecek mi?

Yanıtlar:


10

Dönüşümü dolaylı hale getirebilirsiniz:

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

Aslında geçersiz kılmanıza gerek yok composeve andThenbelki de Scala derleyicisi henüz Java 8 varsayılan arayüz yöntemlerini bilmiyor. (DÜZENLEME: 2.10.3'te çalışmalıdır.)

Ayrıca, Scala lambdas (yani x => ...) 'ı Functionve Scala 2.11'deki diğer SAM türlerini ve Java 8 lambdas'ını atayabilirsiniz Function1. (DÜZENLEME: Bu aslında 2.11 yerine Scala 2.12'de eklendi.)


you should be able to assign Scala lambdas- Bu, Scala 2.11'de bir Scala fonksiyonunun Java8 Lambda için bir argüman olarak iletilebileceği anlamına mı geliyor?
Kevin Meredith

Tartışma olarak geçip geçemeyeceği lambda'nın türüne bağlıdır; eğer java.util.function.Consumer[scala.Function1[Integer, String]]öyleyse, o zaman 2.11'den önce de yapılabilir.
Alexey Romanov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.