2010-04-21 35 views
6

Tôi đang chuyển từ scala 2.7 và ra lệnh scala 2.8 và sử dụng đặt hàng. Nó trông khá thẳng về phía trước nhưng tôi đã tự hỏi tôi có thể làm cho nó một chút ít tiết. Ví dụ:Scala 2.8 TreeMap và thứ tự tùy chỉnh

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 

Nếu tôi sau đó cố gắng để tạo ra một TreeMap tôi nhận được một lỗi

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]() 
    ^

Tuy nhiên nếu tôi xác định rõ ràng các đối tượng A như ra lệnh cho nó hoạt động tốt.

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

Tôi có phải chỉ định rõ ràng thứ tự hoặc có định dạng ngắn hơn không?

Cảm ơn

+1

CẢNH BÁO: so sánh ints bằng cách trừ chúng KHÔNG LÀM VIỆC. Cũng áp dụng cho hầu hết các câu trả lời được đưa ra ở đây. http://stackoverflow.com/questions/2728793/java-integer-what-is-faster-comparison-or-subtraction –

+0

... * iff * ints là * big * và có các dấu hiệu ngược lại. Sau đó, số lượng có thể tràn ra tạo ra kết quả ngược lại do các công tắc dấu hiệu. Nhưng nếu bạn đang làm việc với các con số * rằng * gần với 'Int.MAX_VALUE', bạn đã chơi với lửa, đúng không? Tôi nghĩ rằng "thành ngữ trừ" đặc biệt súc tích/hữu ích trong scala vì scala không có biểu thức điều kiện (ternary) có điều kiện (? :) – kornfridge

Trả lời

10

Chú ý từ "ẩn" trong chẩn đoán. Tham số được khai báo là implicit có nghĩa là trình biên dịch sẽ cố gắng tìm một giá trị phù hợp trong phạm vi tại điểm mà bạn gọi hàm tạo. Nếu bạn thực hiện đặt hàng của bạn một giá trị tuyệt đối, ta sẽ đủ điều kiện để điều trị này bởi trình biên dịch:

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

Edit:

Đó dụ hoạt động trong REPL vì REPL bao quanh mã của bạn trong định nghĩa lớp vô hình. Dưới đây là một trong những hoạt tự do đứng:

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

Nếu tôi thử điều đó trong mã của mình, tôi được thông báo "error:' implicit 'modifier không thể được sử dụng cho các đối tượng cấp cao nhất ". Vì vậy, có cách nào để làm điều này cho các đối tượng cấp cao nhất? – Dave

+0

@Dave Không có, nhưng bạn có thể đặt một ẩn trong một đối tượng gói cho gói chứa 'A'. –

+0

@Daniel: Bạn đã thử chưa? Tôi đã làm nhưng bằng cách nào đó đã nhận được rebuffed bởi trình biên dịch. Tôi không biết tôi có làm sai hay không được phép. –

5

Thay vì mở rộng Ordering[A], hãy thử mở rộng Ordered[A]. Cũng giống như vậy:

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

Cách hoạt động là ẩn tiềm năng thấp chuyển đổi Thứ tự [A] thành Đặt hàng [A] cho TreeMap.Thật không may, chúng tôi tuần tự hóa TreeMaps để lưu trữ và lớp thứ tự là một chút dễ bay hơi (một số $ anon $ class). – Dave

13

Tâm trí bạn, có một cách hơi ít tiết của việc tạo ra một Ordering:

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

Ưu điểm chính của Thứ tự là bạn có thể cung cấp nhiều trong số họ cho cùng lớp. Nếu lớp A của bạn thực sự là Ordered, thì bạn nên mở rộng điều đó. Nếu không, thay vì sử dụng implicits, bạn có thể vượt qua một Ordering một cách rõ ràng:

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

Dường như súc tích, dễ hiểu và linh hoạt. – javadba

+0

Đến đây một lần nữa, muốn upvote/bình luận nhưng .. Tôi đã có được làm điều đó! – javadba

Các vấn đề liên quan