2011-11-07 37 views
11

Đã tạo loại mới bằng cách trộn trong một ObservableSet với HashSet, tôi đã mong đợi thay thế sau đó có thể sử dụng loại mới để tạo mới ví dụ như trong "foo" bên dưới. Nhưng điều này không biên dịch, mặc dù sử dụng hình thức dài ban đầu của loại có vẻ tốt (như được hiển thị trong "thanh", bên dưới).Tạo một thể hiện của bí danh loại gây ra lỗi "loại lớp bắt buộc"

Đây có phải chỉ là một tính năng của ngôn ngữ hoặc tôi đã làm gì đó không?

package whatever 

import collection.mutable._ 
object Whatever { 

    type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] 
    class X 


    def foo { 
     new ObservableHashSet[X] 
    } 

    def bar { 
    new HashSet[X] with ObservableSet[X] 
    } 
} 

Lỗi này là ..

error: class type required but scala.collection.mutable.HashSet[scala.Whatever.X] with scala.collection.mutable.ObservableSet[scala.Whatever.X] found 
new ObservableHashSet[X] 

Trả lời

13

Phiên bản ngắn gọn là bạn đã tạo ra một loại bí danh cho một kiểu cấu trúc (mà bạn không thể nhanh chóng).

Đây là một phiên bản đơn giản của những gì bạn đã làm (không hoạt động):

scala> import collection.mutable._ 
import collection.mutable._ 

scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] 
defined type alias ObservableHashSet 

scala> new ObservableHashSet[String] 
<console>:12: error: class type required but scala.collection.mutable.HashSet[String] with scala.collection.mutable.ObservableSet[String] found new ObservableHashSet[String] 

Bây giờ, các lỗi không thực hiện một số nghĩa nào đó, và hãy để tôi cố gắng giải thích lý do tại sao.

Với type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] bạn đang xác định bí danh loại cho loại không phải là loại cụ thể (hoặc, như thông báo lỗi cho biết, không phải là "loại lớp"), vì vậy bạn không thể tạo thể hiện của nó bằng new .

Nhưng điều này (với một bước trung gian, nơi chúng tôi làm tạo ra một kiểu lớp) hoạt động:

scala> class ObservableHashSet[T] extends HashSet[T] with ObservableSet[T] 
defined class ObservableHashSet 

scala> type obs[T] = ObservableHashSet[T] 
defined type alias obs 

scala> new obs[String] 
res1: ObservableHashSet[String] = Set() 

Vì vậy, câu hỏi là: tại sao scala cho phép bạn tạo một loại bí danh mà bạn không thể nhanh chóng? Vâng, type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] là một loại cấu trúc. Mặc dù, như bạn đã thấy trong đoạn mã đầu tiên, bạn không thể tạo một thể hiện của nó, bạn vẫn có thể sử dụng nó: ví dụ: để đặt một ràng buộc cấu trúc vào một đối số của một hàm.

Hãy xem:

scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] 
defined type alias ObservableHashSet 

scala> def test(obsHashSet: ObservableHashSet[String]) : String = {"bingo!"} 
test: (obsHashSet: ObservableHashSet[String])String 

scala> test(new HashSet[String] with ObservableSet[String]) 
res4: String = bingo! 

nhưng nếu chúng ta cố gắng gọi cho thử nghiệm với một lập luận cho rằng không phù hợp với các loại cấu trúc chúng ta có được một loại không phù hợp:

scala> test(new HashSet[String]) 
<console>:13: error: type mismatch; 
found : scala.collection.mutable.HashSet[String] 
required: ObservableHashSet[String] 
+0

Cảm ơn Paulo. Tôi đoán tôi đã suy nghĩ của "loại" như là một loại thay thế vĩ mô .. Tôi sẽ đọc thêm một chút về các loại cấu trúc. thx – Richard

+0

@Richard: cảm ơn bạn đã đặt câu hỏi. Tôi không biết câu trả lời trước khi bạn hỏi và thử nghiệm với "loại" là hướng dẫn. –

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