2013-03-31 14 views
9

Sto aggiornando il mio progetto 2.9. * In 2.10. Ho diverse classi per tipi fondamentali (angoli, lunghezze, ecc.) Che sembrano candidati perfetti per i tipi di valore. Sfortunatamente, il mio codice Java che usa questi tipi non sta compilando, e non riesco a capire perché. L'ho semplificato in un set di codice molto semplice. Qualsiasi suggerimento sarebbe molto apprezzato.utilizzando Scala 2.10.1 Tipi di valore in Java

classe Angolo Definizione (Scala)

package com.example.units 

class Angle(val radians : Double) extends AnyVal 
{ 
    def degrees = radians * 180.0/math.Pi 
} 

object Angle 
{ 
    val Zero = new Angle(0) 
} 

Test Case Angle (dolorosamente scritto in Java)

package com.example.units; 

import junit.framework.Assert; 
import org.junit.Test; 

public class AngleTest 
{ 
    @Test 
    public static void TestZero() 
    { 
     Angle a = Angle.Zero(); 
     Assert.assertEquals(a.degrees(), 0, 1E-9); 

    } 

} 

Quando compilo, ottengo questo errore:

AngleTest.java:19 incompatible types 
found :double 
required: com.example.units.Angle 
Angle a = Angle.Zero(); 

      ^

Sembra s a me come se Angle.Zero fosse restituito come un doppio, non un angolo. Ho provato ad aggiungere i metodi box/unbox, ma continuo a ricevere lo stesso errore. Ancora una volta, qualsiasi aiuto sarebbe molto apprezzato.

risposta

10

Il compilatore Scala trasforma le classi di valore nel loro tipo unboxed, eliminando il loro costo per il runtime. Ispezione del file di classe compilato per Angle, vedrete:

public static double Zero(); 

Quindi dal punto di vista di Java, Angle.Zero restituisce un doppio; non è a conoscenza della semantica delle classi di valore di Scala.

propri metodi

angolari, quali degrees, vengono compilati in a) un metodo di estensione statico che assume il valore unboxed (double) b) un metodo di istanza:

public static double degrees$extension(double); 
public double degrees(); 

che significa il secondo può essere ancora chiamato su un'istanza di Angle in Java:

Angle a = new Angle(0); 
Assert.assertEquals(a.degrees(), 0, 1E-9); 
+0

Grazie per la risposta. Uso un po 'i metodi factory nelle mie classi companion (Angle.fromDegrees(), Angle.fromRadians(), etc) per migliorare la leggibilità. In questo momento tutti questi metodi hanno lo stesso problema descritto sopra. Mi sembra che ci dovrebbe essere un modo per farlo funzionare. – fbl

+1

Sono decisamente curioso di vedere un modo per farlo funzionare. Dopo aver provato alcuni accorgimenti, nulla sembra elegante (ad esempio, nei test Java, è possibile racchiudere il valore ricevuto dalla chiamata .Zero() in un angolo, ma ciò riduce la leggibilità). Penso che la causa principale qui è che le classi di valore di Scala non sono progettate per la stessa interoperabilità con Java come le classi regolari sono; sono solo un'astrazione in fase di compilazione per semplificare il tuo codice Scala. Suggerisco di utilizzare classi regolari nel tuo caso. –

+0

Purtroppo sono giunto alla stessa conclusione. Se questo non è un bug, allora è almeno un difetto di progettazione con i tipi di valore. Uno dei punti di forza di Scalas è la sua capacità di interoperare nativamente con il codice Java. Eviterò di usarli fino a quando non sarà indirizzato. – fbl

Problemi correlati