2010-11-15 36 views
7

9 lần trong số 10, bạn chỉ cần sử dụng MapSet cư xử như tôi mong đợi họ sẽ, nhưng đôi khi tôi bất ngờ nhấn vớiTại sao Bản đồ và Đặt bí danh trong scala.Predef?

error: type mismatch; 
[INFO] found : scala.collection.Set[String] 
[INFO] required: Set[String] 

Như một ví dụ, từ REPL:

scala> case class Calculator[+T](name: String, parameters: Set[String]) 
defined class Calculator 

scala> val binding=Map.empty[String, String] 
binding: scala.collection.immutable.Map[String,String] = Map() 

scala> Calculator("Hello",binding.keySet) 
<console>:9: error: type mismatch; 
found : scala.collection.Set[String] 
required: Set[String] 
     Calculator("Hello",binding.keySet) 
           ^

tôi nghĩ rằng tôi hiểu được lỗi, đó là, các cuộc gọi chức năng trên các loại bí danh trả về các loại thực tế.

Và do đó, có vẻ như với tôi giải pháp là nhập các loại chưa được đặt bí danh. Khi mà mọi tệp khác trong dự án của tôi bây giờ sẽ tạo ra các lỗi không khớp loại, vì vậy tôi sẽ phải nhập nó vào mỗi tệp. Dẫn đến câu hỏi tôi hỏi trong tiêu đề - mục đích của bí danh trong Predef là gì, nếu cuối cùng tôi cần phải nhập gói thực tế?

Sự hiểu biết của tôi có thiếu sót hay trường hợp sử dụng của tôi không phải là trường hợp điển hình hoặc cả hai?

Trả lời

11

Bạn đã chẩn đoán sai sự cố. Nó không phải là nó không nhận ra bí danh loại là cùng loại như những gì nó là răng cưa. Đó là bí danh loại là scala.collection.immutable.Set và điều đó không giống như scala.collection.Set.

Edit: bằng cách này, tôi nghĩ rằng tôi muốn cố định này, như chứng tỏ bởi những nhận xét trong chẩn đoán loại:

... Also, if the 
* type error is because of a conflict between two identically named 
* classes and one is in package scala, fully qualify the name so one 
* need not deduce why "java.util.Iterator" and "Iterator" don't match. 

Rõ ràng cần làm việc nhiều hơn.

Chỉnh sửa 7/17/2010: OK, tôi mất một thời gian rất đáng kinh ngạc, nhưng giờ ít nhất nó nói điều gì đó khó hiểu.

files/neg/type-diagnostics.scala:4: error: type mismatch; 
found : scala.collection.Set[String] 
required: scala.collection.immutable.Set[String] 
    def f = Calculator("Hello",binding.keySet) 
            ^
+0

Cảm ơn - Điều đó có ý nghĩa khi tôi nhìn vào nó. Nhưng tôi đoán câu hỏi của tôi sẽ trở thành 'Làm thế nào tôi có thể làm cho mã này làm những gì tôi muốn với tối thiểu cruft?' Nếu tôi cần phải chuyển đổi/chuyển đổi từ kiểu này sang kiểu khác cũng như sử dụng tên đủ điều kiện cho một ca sử dụng đơn giản như trường hợp trên, tôi cho rằng tôi phải làm sai. – Jim

+0

Bạn luôn có thể gọi .toSet trên bộ sưu tập bất kỳ để có được bộ không thay đổi. Bạn có thể hoặc có thể không làm điều gì đó sai: điều này chủ yếu chỉ là những gì xảy ra khi bạn mặc định bất biến nhưng cả thế giới (bao gồm cả thế giới của riêng bạn) không cung cấp cho bạn những thứ bất biến. – extempore

+0

lý do tại sao immutable.Map # keySet không trả về một biến đổi.Set? – gerferra

2

Vấn đề thực sự là scala.collection.immutable.Map#keySet trả về một scala.collection.Set (một chỉ đọc Set) thay vì một scala.collection.immutable.Set (một bất biến Set). Tôi sẽ để lại nó cho người khác để giải thích lý do tại sao đó là ...

Sửa

Có người yêu cầu một lời giải thích cho các kiểu trả về của Map#keySet trong this thread, nhưng không nhận được một câu trả lời.

+3

Tôi sẽ sửa chữa. http://lampsvn.epfl.ch/trac/scala/ticket/4001 – extempore

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