java scala type-conversion typesafe

Convierta la unidad Scala en Java Void



type-conversion typesafe (3)

Tengo una clase Java que toma la Function[String, Void] , que es similar a Consumer interfaz funcional del Consumer .

Entonces esta clase debería usar Consumer . Para una primera aproximación, la Function<String, Void> nunca es el tipo correcto de usar. Si no puede cambiarlo, al menos tenga en cuenta que es un mal diseño y tenga cuidado con esta biblioteca. La respuesta de Som-snytt ya muestra cómo llamar correctamente la temp desde Scala, y es simple escribir una conversión implícita de String => Unit a Function[String, Void] si lo desea. Así que el resto de esta respuesta se trata de por qué tus otros intentos no funcionaron.

ya que es equivalente anulado

Precisamente: es equivalente a void , no Void . El código Java equivalente llamaría a un método void , por ejemplo, Consumer.accept :

public void tempOfVoid(Consumer<String> f) { temp(new Function<String, Void> { public Void apply(String x) { return f.accept(x); } }; }

y no podrá verificar el tipo. En cambio, necesitas

public Void apply(String x) { f.accept(x); return null; }

lo mismo que se muestra en Scala por la respuesta de som-snytt.

Ahora, puede preguntar: ¿qué sucede cuando Unit es un argumento de tipo, porque void no puede ser, o cuando el valor de tipo Unit necesita ser representado en tiempo de ejecución (un ejemplo sería val x: Any = () )? En esos casos, la Unit está representada por la clase scala.runtime.BoxedUnit , al igual que Int se suele traducir a int pero a veces a java.lang.Integer . Esto explica por qué el lanzamiento a Void arroja una excepción (y no da como resultado un error de compilación). Void no es una traducción adecuada para estos casos porque no tiene valores (no null ) mientras que Unit tiene exactamente uno: () .

Tengo una clase Java que toma la Function[String, Void] , que es similar a Consumer interfaz funcional del Consumer . Estoy llamando a esta función de Java desde el código de Scala. Como puede ver a continuación, acepto la function: => Unit en el lado de Scala ya que es equivalente anulada. Cuando intento aplicar esta función en lugar del tipo de devolución de Void ocurre una discrepancia. La conversión explícita de .asInstanceOf[Void] también arrojó una excepción. ¿Cómo convertimos => Unit a => Void ?

// Java class AcceptFunction { public void temp(Function<String, Void> f) { f.apply("Hello"); } } // Scala def temp(f: String => Unit): Unit = { new AcceptFunction().temp(new Function[String, Void]() { override def apply(t: String): Void = f(t) // <===== error expecting Void instead of Unit }) }


Aparentemente,

scala> new jfunc.Acceptor().f(s => println(s)) <console>:12: error: type mismatch; found : Unit required: Void new jfunc.Acceptor().f(s => println(s)) ^ scala> new jfunc.Acceptor().f { s => println(s) ; null } hello, world.

donde la java es como usted muestra:

package jfunc; import java.util.function.*; public class Acceptor { public void f(Function<String, Void> g) { g.apply("hello, world."); } }

lo hace:

scala> :javap -c - public static final java.lang.Void $anonfun$res0$1(java.lang.String); Code: 0: getstatic #33 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: aload_0 4: invokevirtual #37 // Method scala/Predef$.println:(Ljava/lang/Object;)V 7: aconst_null 8: areturn public $line3.$read$$iw$$iw$(); Code: 0: aload_0 1: invokespecial #39 // Method java/lang/Object."<init>":()V 4: aload_0 5: putstatic #41 // Field MODULE$:L$line3/$read$$iw$$iw$; 8: aload_0 9: new #43 // class jfunc/Acceptor 12: dup 13: invokespecial #44 // Method jfunc/Acceptor."<init>":()V 16: invokedynamic #63, 0 // InvokeDynamic #0:apply:()Ljava/util/function/Function; 21: invokevirtual #67 // Method jfunc/Acceptor.f:(Ljava/util/function/Function;)V 24: getstatic #72 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit; 27: putfield #74 // Field res0:Lscala/runtime/BoxedUnit; 30: return


Debe usar el tipo de consumidor no Function , ya que su Function no tiene salida, y el Consumer se utiliza para este escenario. me gusta:

class AcceptFunction { public void temp(Consumer<String> f) { // Consumer for no output Function f.accept("Hello"); } } def temp(f: String => Unit): Unit = { new AcceptFunction().temp(new Consumer[String]() { override def accept(t: String): Unit= f(t) }) }