2011-06-22 53 views
13

Có sự khác biệt giữa mã này:gán giá trị bên trong cho vòng lặp trong Scala

for(term <- term_array) { 
     val list = hashmap.get(term) 
     ... 
    } 

và:

for(term <- term_array; val list = hashmap.get(term)) { 
     ... 
    } 

Bên trong vòng lặp Tôi đang thay đổi hashmap với một cái gì đó giống như

này
hashmap.put(term, string :: list) 

Trong khi kiểm tra người đứng đầu list có vẻ như đã lỗi thời bằng cách nào đó khi sử dụng đoạn mã thứ hai.

Trả lời

9

instantiating các biến bên trong cho các vòng lặp có ý nghĩa nếu bạn muốn sử dụng biến đó câu lệnh for, như:

for (i <- is; a = something; if (a)) { 
    ... 
} 

Và lý do tại sao danh sách của bạn là lỗi thời, là điều này chuyển tới một cuộc gọi foreach, chẳng hạn như:

term_array.foreach { 
    term => val list= hashmap.get(term) 
} foreach { 
    ... 
} 

Vì vậy, khi bạn đạt ..., hashmap của bạn đã được thay đổi. Ví dụ khác chuyển thành:

term_array.foreach { 
    term => val list= hashmap.get(term) 
    ... 
} 
17

Sự khác biệt giữa hai là, giá trị đầu tiên là định nghĩa được tạo bởi mẫu khớp và giá trị thứ hai là giá trị bên trong hàm theo nghĩa đen. Xem Programming in Scala, Section 23.1 For Expressions:

for { 
    p <- persons    // a generator 
    n = p.name    // a definition 
    if (n startsWith "To") // a filter 
    } yield n 

Bạn thấy sự khác biệt thực sự khi bạn biên dịch nguồn với scalac -Xprint:typer <filename>.scala:

object X { 
    val x1 = for (i <- (1 to 5); x = i*2) yield x 
    val x2 = for (i <- (1 to 5)) yield { val x = i*2; x } 
} 

Sau khi mã biến đổi bởi trình biên dịch bạn sẽ nhận được một cái gì đó như thế này:

private[this] val x1: scala.collection.immutable.IndexedSeq[Int] = 
    scala.this.Predef.intWrapper(1).to(5).map[(Int, Int), scala.collection.immutable.IndexedSeq[(Int, Int)]](((i: Int) => { 
    val x: Int = i.*(2); 
    scala.Tuple2.apply[Int, Int](i, x) 
    }))(immutable.this.IndexedSeq.canBuildFrom[(Int, Int)]).map[Int, scala.collection.immutable.IndexedSeq[Int]]((
    (x$1: (Int, Int)) => (x$1: (Int, Int) @unchecked) match { 
     case (_1: Int, _2: Int)(Int, Int)((i @ _), (x @ _)) => x 
    }))(immutable.this.IndexedSeq.canBuildFrom[Int]); 

private[this] val x2: scala.collection.immutable.IndexedSeq[Int] = 
    scala.this.Predef.intWrapper(1).to(5).map[Int, scala.collection.immutable.IndexedSeq[Int]](((i: Int) => { 
    val x: Int = i.*(2); 
    x 
    }))(immutable.this.IndexedSeq.canBuildFrom[Int]); 
+0

Thú vị. Liệu kết quả biến đổi có thể biến đổi thành một thứ gì đó mà con người có thể đọc được không? – Suma

+0

@Suma không chắc chắn ý bạn là gì. Đầu ra của trình biên dịch là mã Scala hợp lệ (trừ một số vấn đề tạo tác in ấn nhỏ). Bạn không thể có được mức cao hơn hoặc dễ đọc hơn thế. – sschaef

+0

Để dễ hiểu hơn, người ta có thể loại bỏ một số phần hợp lệ, nhưng không cần thiết, như chú thích kiểu, hoặc 'canBuildFroms' khi không cần thiết, để nó trông giống như một cái gì đó mà con người viết. Tôi đoán nó là một công việc nhàm chán, nhưng có lẽ nó sẽ làm cho lý do cốt lõi tại sao việc xử lý là rõ ràng hơn. Tôi có thể thử nó sau này, nếu bạn không nghĩ rằng nó là giá trị nỗ lực của bạn. – Suma

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