2009-04-25 39 views
5

Tôi có một lớp học mà tôi muốn sử dụng trong một scala.collection.mutable.PriorityQueue, nhưng tôi không muốn làm cho nó được đặt hàng [A] chỉ cho một mục đích này. Tôi không xem xét thứ tự tôi muốn sử dụng liên quan đến PriorityQueue như thứ tự tự nhiên của lớp.Scala: Có cách nào để sử dụng PriorityQueue như tôi làm trong Java không?

class MyObject (sequence: Int, values: List[String]) ... 

Vì vậy, trong PriorityQueue, tôi muốn các giá trị được sắp xếp theo 'chuỗi'. Tuy nhiên, chỉ vì hai đối tượng có cùng trình tự không làm cho chúng tự nhiên như nhau vì nội dung của 'giá trị' của chúng có thể khác nhau.

Đây là nơi, trong Java, thật tuyệt khi có thể cung cấp đối tượng Comparator thay thế cho PriorityQueue. Comparator của tôi sẽ chỉ đơn giản là đặt hàng các đối tượng liên quan đến 'chuỗi' của họ và bỏ qua 'giá trị' của họ.

Lớp PriorityQueue phải được tham số với "Một <% Ordered [A]"

class PriorityQueue[A <% Ordered[A]] extends ... 

Từ những gì tôi đã đọc, điều này có nghĩa lớp của tôi phải mở rộng Ordered [A] hoặc tôi phải cung cấp một chuyển đổi loại "ngầm định" thành Ordered [A], thành thật mà nói, cảm thấy không phù hợp.

Giải pháp Java có vẻ "chức năng" hơn cho phép tôi chuyển đối tượng giống như hàm so sánh thay vì buộc tôi vào một hệ thống phân cấp lớp hoặc monkeypatching lớp của tôi.

Tôi nhận thấy có những lựa chọn thay thế để sử dụng PrioirityQueue, nhưng tôi cảm thấy như tôi có thể gặp phải đường cong học tập Scala ở đây và không muốn từ bỏ mà không khám phá quyết định thiết kế này đầy đủ.

Đây có phải là một quyết định không may trong thư viện Scala hay tôi hiểu nhầm một số loại quy ước gọi điện mà làm cho PriorityQueue dễ sử dụng hơn và 'chức năng'?

Cảm ơn

Trả lời

9

Cú pháp

class PriorityQueue[A <% Ordered[A]] ... 

thực sự chỉ là một sugaring ánh sáng trên đầu trang của

class PriorityQueue[A]()(implicit convert: A => Ordered[A]) ... 

Điều này có nghĩa bạn có thể viết phương pháp riêng của bạn A => Ordered [A]

case class Foo(n: Int) 
def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] { 
    def compare(other: Foo) = f.n.compare(other.n) 
} 

Và chuyển thủ công nó vào hàm tạo PriorityQueue của bạn

new PriorityQueue[Foo]()(orderedFoo) 
3

Chức năng chuyển đổi của A thành Đặt hàng [A] có thể đóng vai trò so sánh Java. Hàm cần được hiển thị chỉ trong phạm vi nơi bạn tạo PriorityQueue, vì vậy nó sẽ không trở thành "thứ tự tự nhiên" cho đối tượng của bạn.

2

Kết hợp cả hai (đúng) câu trả lời trước một này vào mã compilable:

object o { 
    case class Foo(n: Int) 
    implicit def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] { 
    def compare(other: Foo) = f.n.compare(other.n) 
    } 

    val x = new scala.collection.mutable.PriorityQueue[Foo]() 
} 

dụ của ông sẽ không biên dịch cho bạn chỉ vì (tôi giả), bạn ném nó vào trình biên dịch như nó vốn có. Bạn không thể biên dịch các phương thức mức cao nhất trong scala, mọi thứ phải nằm trong một đối tượng.

2

Trong scala 2.8.0, PriorityQueue thay đổi để

class PriorityQueue[A](implicit ord : Ordering[A]) 

Và Thứ tự [A] trong Scala cũng tương tự như trong Java sánh

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