2013-03-31 5 views
9

2.9. * 프로젝트를 2.10으로 업데이트합니다. 가치 유형에 대한 완벽한 후보자 인 것처럼 보이는 기본 유형 (각도, 길이 등)에 대한 여러 클래스가 있습니다. 불행히도 이러한 유형을 사용하는 Java 코드는 컴파일되지 않으며 이유를 파악할 수 없습니다. 간단한 코드 세트로 간략화했습니다. 어떤 제안이라도 대단히 감사 할 것입니다.Scala 2.10.1 Java의 값 유형

각 클래스 정의 I 컴파일 할 때이 오류가 수 (스칼라) (고통스럽게 자바로 작성된)

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

각 테스트 케이스

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

    } 

} 

:

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

      ^

Angle.Zero가 Angle이 아닌 Double로 리턴됩니다. 상자/unbox 메서드를 추가했지만 동일한 오류가 계속 발생했습니다. 다시 한번, 어떤 도움이라도 대단히 감사하겠습니다.

답변

10

스칼라 컴파일러는 값 클래스를 unboxed 형식으로 변환하여 런타임 비용을 없앱니다. Angle의 컴파일 된 클래스 파일을 검사, 당신은 볼 수 있습니다 : 그래서보기 자바의 관점에서

public static double Zero(); 

이 Angle.Zero 이중 반환 스칼라의 가치 클래스의 의미를 알지 못한다. 후자가 계속 될 수 있음을 의미

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

: 예 degrees 같은

각도 자체 방법, double 박싱 값 (걸린 a) 정적 인 연장 방법) b) 인스턴스 메소드 컴파일 얻을 자바 Angle의 인스턴스에서 호출 : 답장을

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

감사합니다. 가독성을 높이기 위해 필자는 동반자 클래스 (Angle.fromDegrees(), Angle.fromRadians() 등)에서 팩토리 메소드를 사용합니다. 현재이 모든 방법은 위에서 설명한 것과 동일한 문제가 있습니다. 이 일을하는 방법이 있어야한다고 생각합니다. – fbl

+1

나는 그것이 효과를 발휘할 수있는 방법을 알기에 확실히 궁금합니다. 몇 가지 해결 방법을 시도했지만 우아하지는 않습니다. 예를 들어 Java 테스트에서 .Zero() 호출에서받은 값을 각도로 래핑 할 수 있지만 가독성은 떨어집니다. 여기서 근본적인 원인은 스칼라의 값 클래스가 일반 클래스처럼 자바와 동일한 상호 운용성을 위해 설계되지 않았다는 것입니다. 그것들은 단지 스칼라 코드를 단순화하기위한 컴파일 타임 추상화 일뿐입니다. 나는 당신의 경우에 정규 수업을 사용하도록 권합니다. –

+0

불행히도 나는 같은 결론에 도달했습니다. 이것이 버그가 아니라면, 적어도 값의 유형이있는 디자인상의 결함입니다. Scalas의 강점 중 하나는 Java 코드를 기본으로 상호 운용 할 수 있다는 것입니다. 나는 그것이 견딜 때까지 사용하지 않을 것이다. – fbl