2011-10-10 5 views
1

다음 예제를 고려해보십시오. A.Value + B.ValueB.Value이 문자열이어야한다고 생각하는 이유는 무엇입니까? 어떻게 수정해야합니까?스칼라에서 일반 형식의 하위 형식 지정

타입 안전상의 이유로
object Catano extends App { 
    val const3 = new Constant(3) 
    val const5 = new Constant(5) 

    val block = new Arithmetic(const3.Result, const5.Result) 

    println(block.Sum.Value) 
} 

class Block 

class Arithmetic[T: Numeric](val A: Connector[T], val B: Connector[T]) extends Block { 
    def Sum = new Connector({ A.Value + B.Value }) 
} 

class Constant[T](x: T) extends Block { 
    def Result = new Connector({ x }) 
} 

class Connector[T](f: => T) { 
    def Value: T = f 
} 

, 타입 예외로 실패 할 경우 다음과 같은 :

val const3 = new Constant("ping") 
    val const5 = new Constant("pong") 

    val block = new Arithmetic(const3.Result, const5.Result) 
+1

'scala.math.Numeric.Implicits_'를 가져온다면, 이것은 8을 인쇄합니다. 또한, 대문자 사용은 분명히 C# -ish입니다. 멤버'val'과'def'는 일반적으로 소문자로 시작합니다. – Dylan

답변

6

귀하의 문제는 재현 할 수 있습니다

class C[T: Numeric] {def add(a: T, b: T) = a+b } 
error: type mismatch; 
found : T 
required: String 

것은이 일어나고 무엇 :에 자바 에서처럼 스칼라, 당신은 String + 아무것도 할 수 있고, 또한 + String. java와는 달리 pperators는 정상적인 메소드 호출 일 뿐이며, 각 유형에 상응하는 + 메소드가 있음을 암시하는 것처럼 보입니다. 물론, 자바 타입에는 그러한 메소드가 없으므로 그렇지 않습니다. 우리가 가지고있는 것은 을 Predef에 넣었습니다. 이렇게하면 +을 암시 적 변환으로 사용할 수 있습니다. 코드에서 이것은 + 사용 가능한 유일한 것입니다. 따라서 B.ValueString이 아닙니다.

이제 +을 사용할 수 없습니까? T:Numeric은 암시 적 범위에 Numeric[T] 값이 있어야합니다. 어떤 유형 T가 있어야하고 어떤 방법이 T에 사용 가능한지에 대해서는 아무 것도 말하지 않습니다. 이 Numeric[T] 인스턴스에는 def plus(x: T, y: T): T 메서드가 있습니다. 그만으로 T에서 +을 사용할 수 없습니다. 더하기를 직접 호출 할 수는 있지만 이는 불리합니다.

import Numeric.Implicits._ 
0

이 작동 :

class Arithmetic[ T <: Int] (val A: Connector[T], val B: Connector[T]) extends Block { 
    def Sum = new Connector({ A.Value + B.Value }) 
} 

숫자를 다행히 plus에 위임 +은 당신이 범위에서 일부 implicits를 넣어 제공합니다 (+(String)Predef에 있었다처럼) 암시 적 변환하여 추가 할 수 있습니다 + 함수를 가지고 있지 않습니다.

+0

그게 내 문제를 해결하는 방법에 대한 간단하고 좋은 예입니다 :-) –

+0

T <: Int의 요점은, Int는 서브 클래스 화 될 수 없다는 것입니다. –

+0

예 ... 사실 ... Int와 Int 만 지정하는 올바른 방법은 무엇입니까? –