2010-04-21 6 views
6

나는 scala 2.7에서 바꾸고 있고 scala 2.8로 명령하고있다. 그것은 꽤 똑바로 보입니다.하지만 좀 덜 장황하게 만들 수 있을지 궁금합니다. 예를 들면 : 나는 다음 트리 맵을 만들려고하면 내가 명시 적으로 주문하는 것은 잘 작동으로 객체 A를 지정하면스칼라 2.8 TreeMap과 커스텀 주문

scala> case class A(i: Int) 
defined class A 
scala> object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i} 
defined module A 

나는

scala> new collection.immutable.TreeMap[A, String]() 
<console>:10: error: could not find implicit value for parameter ordering: Ordering[A] 
     new collection.immutable.TreeMap[A, String]() 
    ^

그러나 오류가 발생합니다.

scala> new collection.immutable.TreeMap[A, String]()(A) 
res34: scala.collection.immutable.TreeMap[A,String] = Map() 

항상 주문을 명시 적으로 지정해야합니까, 아니면 더 짧은 형식입니까?

감사합니다.

+1

경고 : 정수를 뺀 값을 뺀 값과 비교하십시오. 여기에 주어진 대부분의 답변에도 적용됩니다. http://stackoverflow.com/questions/2728793/java-integer-what-is-faster-comparison-or-subtraction –

+0

... * iff * 정수가 * 크고 * 반대 기호가 있습니다. 그러면 부호가 바뀌기 때문에 숫자가 오버플로되어 반대 결과를 얻을 수 있습니다. 그러나 만약 당신이 * Int.MAX_VALUE에 가까운 숫자로 작업한다면, 당신은 이미 불을 가지고 놀고있는 것 아닙니까? scala는 (삼항) 조건식을 가지고 있지 않기 때문에 scala에서 빼기 "관용구"가 특히 간결하고 유용하다고 생각합니다 (? :) – kornfridge

답변

10

진단에 "암시 적"이라는 단어가 있음을 확인하십시오. 매개 변수는 implicit으로 선언되어 컴파일러는 생성자를 호출하는 시점에서 범위에서 적절한 값을 찾으려고합니다. 당신이 당신이 암시 적 값을 주문 할 경우, 컴파일러에 의해이 치료를받을 수 있습니다 :

scala> implicit object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i} 
defined module A 

scala> val tm1 = new collection.immutable.TreeMap[A, String]() 
tm1: scala.collection.immutable.TreeMap[A,String] = Map() 

편집 : REPL이 보이지 않는 클래스 정의 코드를 둘러싸 때문에 예는 REPL에서 작동

. 여기에 무료 서 작동 하나는 다음과 같습니다

대신 Ordering[A]을 확장
case class A(val i:Int) extends Ordered[A] { def compare(o:A) = i - o.i } 

object A { implicit object AOrdering extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i } } 

class B { 
    import A.AOrdering 

    val tm1 = new collection.immutable.TreeMap[A, String]() 
} 
+0

코드에서 이것을 시도하면 "오류 : 암시 적"수식어를 사용할 수 없습니다 최상위 오브젝트 용 "을 선택하십시오. 최상위 수준의 객체에 대해 이렇게하는 방법이 있습니까? – Dave

+0

@Dave 'A'가 들어있는 패키지에 패키지 객체를 넣을 수는 있습니다. –

+0

@Daniel : 시도 했습니까? 내가했지만 어떻게 든 컴파일러에 의해 rebuffed있어. 방금 잘못했는지 또는 실제로 허용되지 않았는지 나는 알 수 없습니다. –

5

, Ordered[A]을 확장하려고합니다. 그래서 같이 : 같은 클래스의 대다수를 제공 할 수있는 주문의

implicit val OrderingA = Ordering.by((_: A).i) 

가장 큰 장점 :

scala> case class A(val i:Int) extends Ordered[A] {def compare(o:A) = i-o.i} 
defined class A 

scala> A(1)<A(2) 
res0: Boolean = true 

scala> A(1)<A(0) 
res1: Boolean = false 

scala> new collection.immutable.TreeMap[A, String]() 
res3: scala.collection.immutable.TreeMap[A,String] = Map() 
+1

작동 방식은 낮은 우선 순위가 암시 적으로 TreeMap의 Ordered [A]를 Ordering [A]로 변환한다는 것입니다.불행하게도 우리는 저장을 위해 TreeMaps를 직렬화하고 정렬 클래스는 약간 휘발성 (일부 $$ anon $ 클래스)입니다. – Dave

13

마음 당신은 Ordering를 만드는 약간 덜 자세한 방법이있다. A 클래스가 실제로 Ordered 인 경우이를 확장해야합니다. 그렇지 않은 경우 암시를 사용하는 대신 명시 적으로 주문을 전달할 수 있습니다.

new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i)) 
+0

간결하고 이해할 수 있으며 유연합니다. – javadba

+0

다시 여기 왔는데, upvote/comment하고 싶었지만 .. 이미 그곳에갔습니다! – javadba