2011-08-23 46 views
6

Tôi nhận được thông báo lỗi về "lỗi: đối số kiểu [Bất kỳ] không tuân theo đặc điểm loại tham số Cloneable của [+ A <: AnyRef]", mà tôi có thể 't làm cho người đứng đầu hoặc đuôi của.Thêm vào bản đồ scala trong vòng lặp cho câu lệnh vòng lặp và điều kiện

Cụ thể,

var M = mutable.Map[Int, mutable.Set[Int]]() 
for(i <- 1 to 100; j <- 1 to 100) { 
    if(!M.contains(i)) {M += i -> mutable.Set[Int](j)} 
    else {M(i) += j} 
} 

(Tôi thực sự cố gắng một cái gì đó phức tạp hơn, nhưng điều này là mã tạo lỗi chỉnh và đơn giản hóa đến mức tối thiểu)

Và dòng cuối cùng của đoạn mã trên tạo thông báo lỗi. Nếu tôi chia nhỏ hơn nữa

for(i <- 1 to 100; j <- 1 to 100) { 
    if(!M.contains(i)) {M += i -> mutable.Set[Int](j)} 
} 

nó hoạt động!

Làm cách nào để mã trên hoạt động?

+1

là một lưu ý phụ, 'M + = i -> (M.getOrElse (i, mutable.Set [Int]()) + j)' sẽ là một cách thành ngữ hơn một chút để viết phần thân của vòng lặp. –

+0

@Travis Cảm ơn! Đó là giải pháp tôi đang tìm kiếm. Nếu bạn chuyển đổi nhận xét của mình thành câu trả lời, tôi rất sẵn lòng chọn nhận xét đó. – JasonMond

+0

Cảm ơn, nhưng tôi nghĩ rằng các câu trả lời dưới đây có thể làm tốt hơn trong việc giải quyết các câu hỏi như đặt ra? –

Trả lời

6

Tôi đã giảm ví dụ của bạn hơn nữa:

scala> if(!M.contains(1)) {M += 1 -> mutable.Set[Int](1)} else {M(1) += 1}; 
<console>:9: error: type arguments [Any] do not conform to trait Cloneable's type parameter bounds [+A <: AnyRef] 
val res17 = 
    ^

Vấn đề dường như xảy ra khi biên dịch cố gắng tìm kiểu trả chung cho cả hai ngành: Người đầu tiên là

scala> M += 1 -> mutable.Set[Int](1) 
res19: scala.collection.mutable.Map[Int,scala.collection.mutable.Set[Int]] = ... 

Và phần "khác" là

scala> M(1) += 1 
res18: scala.collection.mutable.Set[Int] = Set(1) 

Nếu tôi thêm giá trị trả về cho kết thúc o f biểu thức này, REPL ăn nó mà không có lỗi:

scala> if(!M.contains(1)) {M += 1 -> mutable.Set[Int](1)} else {M(1) += 1}; println("hello") 
hello 

Vì loại trả về của biểu thức là Đơn vị.

+0

Cảm ơn! Bây giờ tôi đã hiểu được thông báo lỗi. Nhưng công việc xung quanh thì quá kỳ quặc. Tôi chắc rằng có một cách suôn sẻ, chính thống hơn để làm điều này. – JasonMond

7

Digal chẩn đoán vấn đề (không thống nhất các loại nhánh nếu không) và trông giống như lỗi trình biên dịch. Dưới đây là một trường hợp tiếp tục đơn giản hóa mà sẽ cung cấp một lỗi trong REPL, sau một thời gian biên soạn dài,

if (true) { 
    null: collection.mutable.Map[Int, Int] 
} else { 
    null: collection.mutable.Set[Int] 
} 

Trong khi đó, bạn có thể nhận được mã của bạn để biên dịch với một loại rõ ràng rắc đâu đó trong báo cáo kết quả if-else ,

for(i <- 1 to 100; j <- 1 to 100) { 
    if(!M.contains(i)) {M += i -> mutable.Set[Int](j)} 
    else {M(i) += j}: Unit 
} 

tôi nộp một vấn đề ở đây: https://issues.scala-lang.org/browse/SI-4938

+1

Wow! Tôi chưa bao giờ là người khám phá ra một lỗi bona fide trong một trình biên dịch đã được thiết lập trước đó. – JasonMond

+1

Xin chúc mừng: -) ... –

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