2010-10-13 46 views
7

Tôi muốn viết một bí danh loại để rút ngắn mã Scala đẹp và được đóng gói. Giả sử tôi có một số bộ sưu tập có thuộc tính là danh sách bản đồ, giá trị là các bộ dữ liệu. Loại của tôi sẽ viết một cái gì đó như List[Map[Int, (String, String)]] hoặc bất kỳ thứ gì chung chung hơn như ứng dụng của tôi cho phép nó. Tôi có thể tưởng tượng có một siêu người yêu cầu Seq[MapLike[Int, Any]] hoặc bất cứ điều gì nổi thuyền của tôi, với các lớp con cụ thể là cụ thể hơn.Bí danh loại Scala bao gồm đối tượng đồng hành [người mới bắt đầu]

Sau đó tôi muốn viết bí danh cho loại dài này.

class ConcreteClass { 
    type DataType = List[Map[Int, (String, String)]] 
    ... 
} 

Tôi sẽ vui vẻ sử dụng ConcreteClass#DataType ở mọi nơi tôi có thể sử dụng và sử dụng nó.

Bây giờ giả sử tôi thêm một chức năng

def foo(a : DataType) { ... } 

Và tôi muốn gọi nó từ bên ngoài với một danh sách rỗng. Tôi có thể gọi foo(List()), nhưng khi tôi muốn thay đổi loại cơ bản của mình thành một loại khác là Seq, tôi cũng sẽ phải quay lại và thay đổi mã này. Bên cạnh đó, nó không phải là rất rõ ràng danh sách trống này được thiết kế như là một DataType. Và đối tượng đồng hành không có phương thức List được liên kết, vì vậy tôi không thể gọi DataType() hoặc DataType.empty. Sẽ càng khó chịu hơn khi tôi cần những danh sách không trống vì tôi sẽ phải viết ra một phần quan trọng của loại dài này.

Có cách nào tôi có thể yêu cầu Scala hiểu loại của tôi là giống nhau không, kể cả đối tượng đồng hành với các phương thức tạo của nó, vì lợi ích của việc rút ngắn mã và bôi đen nó? Hoặc, tại sao tôi không nên làm điều này ngay từ đầu?

Trả lời

7

Câu trả lời là thực sự khá đơn giản:

class ConcreteClass { 
    type DataType = List[String] 
} 
object ConcreteClass { 
    val DataType = List 
} 
val d = ConcreteClass.DataType.empty 

Điều này cho phép mã của tôi để gọi ConcreteClass.DataType để xây dựng danh sách với tất cả các phương pháp trong Danh sách và ít nỗ lực.

Cảm ơn rất nhiều đến Oleg vì thông tin chi tiết. Câu trả lời của ông cũng là tốt nhất trong trường hợp bạn không muốn ủy quyền danh sách bất kỳ cuộc gọi đến ConcreteClass.DataType, nhưng kiểm soát chính xác những gì bạn muốn cho phép người gọi để làm.

+2

Nếu bạn không có ý định phân lớp 'ConcreteClass' để ghi đè' DataType', bạn có thể đặt cả hai bí danh 'type' và' val' vào đối tượng đồng hành (thay vì có một lớp trong lớp). Đây là cách các bí danh trong đối tượng gói 'scala' hoạt động. –

+0

Bạn thực sự rất đúng. Tôi sẽ làm điều này từ bây giờ. Cảm ơn. – Jean

+1

Ngoại trừ d là loại Danh sách [Không có gì] – sourcedelica

5

Điều này thì sao?

 
class ConcreteClass { 
    type DataType = List[String] 
} 
object DataType { 
    def apply(): ConcreteClass#DataType = Nil 
} 
//... 
val a = DataType() 

+0

Tác phẩm này hoạt động. Cảm ơn. Tuy nhiên với điều này tôi phải xác định mọi phương pháp của Danh sách để làm những gì tôi muốn, và đó là một chút tiết. Nó rất tốt để có quyền kiểm soát những gì có thể được gọi là quá. Nhờ câu trả lời của bạn Tôi nghĩ rằng tôi đã nhận được giải pháp chung cho "có thể gọi tất cả các phương pháp Danh sách": đăng nó ngay bây giờ. Cảm ơn rất nhiều :) – Jean

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