2011-12-22 25 views
44

đưa ra:Scala Bản đồ foreach

val m = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3) 
m.foreach((key: String, value: Int) => println(">>> key=" + key + ", value=" + value)) 

tại sao các trình biên dịch phàn nàn

error: type mismatch 
found : (String, Int) => Unit 
required: (String, Int) => ? 

Trả lời

25

oops, đọc doco sai, map.foreach mong đợi một hàm có nghĩa đen với đối số tuple!

nên

m.foreach((e: (String, Int)) => println(e._1 + "=" + e._2)) 

làm việc

+4

Với các loại tham gia được phỏng đoán, bạn có thể chỉ cần làm: m.foreach (e => println (e._1 + "=" + e._2) – virtualeyes

+0

Có thể hiển thị đầy đủ loại không? Có rất nhiều Bản đồ –

71

Tôi không chắc chắn về lỗi, nhưng bạn có thể đạt được những gì bạn muốn như sau:

m.foreach(p => println(">>> key=" + p._1 + ", value=" + p._2)) 

Tức là, foreach có chức năng lấy một cặp và trả về Unit, không phải chức năng t mũ có hai đối số: ở đây, p có loại (String, Int).

Cách khác để viết nó là:

m.foreach { case (key, value) => println(">>> key=" + key + ", value=" + value) } 

Trong trường hợp này, khối { case ... } là một chức năng một phần.

+0

đó là tốt đẹp, phù hợp hơn với obj.each ngôn ngữ năng động tiếp cận {k, v => ...} và nhiều hơn nữa dễ đọc hơn tuple ._1, ._2 cú pháp – virtualeyes

+0

Juts tò mò, là có bất kỳ xem xét hiệu suất cho việc sử dụng thứ hai (trường hợp)? Đối với mỗi yếu tố cố gắng 'trường hợp' họ gán cho biến vv Tôi muốn mã của tôi có thể đọc được mà còn để nhanh nhất có thể. – endertunc

13

Bạn cần phải khớp với đối số trên đối số Tuple2 để gán biến cho các phân mục của nó key, value. Bạn có thể thực hiện với rất ít thay đổi:

m.foreach{ case (key: String, value: Int) => println(">>> key=" + key + ", value=" + value)} 
+5

Và bạn có thể xóa chú thích loại khỏi khóa và giá trị, nhân tiện. – Rogach

+0

@huitseeker Tôi yêu bạn rất thân thiết. –

5

xuất sắc câu hỏi! Ngay cả khi gõ một cách rõ ràng phương thức foreach, nó vẫn cho rằng lỗi biên dịch rất không rõ ràng. Có nhiều cách xung quanh nó, nhưng tôi không thể hiểu tại sao ví dụ này không hoạt động.

scala> m.foreach[Unit] {(key: String, value: Int) => println(">>> key=" + key + ", value=" + value)} 
<console>:16: error: type mismatch; 
found : (String, Int) => Unit 
required: (String, Int) => Unit 
       m.foreach[Unit] {(key: String, value: Int) => println(">>> key=" + key + ", value=" + value)} 
                 ^
14

Các thông báo lỗi khó hiểu là một lỗi biên dịch, mà nên fixed in 2.9.2:

+0

Sử dụng scalac 2.9.2 và lỗi này vẫn còn – Renato

+0

Tôi vừa kiểm tra (bằng cách biên dịch https://github.com/paulbutcher/baderrormessage với cả 2.9.1 và 2.9. 2) Tôi có thể thấy vấn đề trong 2.9.1 và không phải trong 2.9.2.Nếu bạn có một ví dụ về vấn đề vẫn còn xảy ra, có lẽ bạn nên mở lại lỗi? –

+0

Tôi vừa thử mã được đăng trong câu trả lời của @ (Eishay Smith) bên dưới (tôi tin là vấn đề tương tự như được nêu trong câu hỏi) với Scala 2.9.2 (Java HotSpot 1.7.0 VM cho Windows 64-bit) và có thể thấy cùng một thông điệp vô lý được hiển thị trong bài đăng của anh ấy. – Renato

0

Tuy nhiên, một cách khác:

Map(1 -> 1, 2 -> 2).foreach(((x: Int, y: Int) => ???).tupled) 

Tuy nhiên nó đòi hỏi các chú thích loại rõ ràng, vì vậy tôi thích chức năng một phần.

1

Documents nói đối số là tuple -> đơn vị, vì vậy chúng tôi có thể dễ dàng làm được điều này

Map(1 -> 1, 2 -> 2).foreach(tuple => println(tuple._1 +" " + tuple._2))) 
Các vấn đề liên quan