2010-06-01 29 views
20

Khi tôi đánh giá một for tại Scala, tôi nhận được một bất biến IndexedSeq (một bộ sưu tập với những đặc điểm mảng như hiệu suất, chẳng hạn như truy cập ngẫu nhiên hiệu quả):Bộ sưu tập kiểu tạo bởi để có năng suất

scala> val s = for (i <- 0 to 9) yield math.random + i 
s: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6127056766832756, 1.7137598183155291, ... 

Liệu một for với yield luôn trả về IndexedSeq hoặc có thể trả lại một số loại thu thập khác (ví dụ: LinearSeq)? Nếu nó cũng có thể trả lại cái gì khác, thì cái gì quyết định kiểu trả về, và làm thế nào tôi có thể ảnh hưởng đến nó?

Tôi đang sử dụng Scala 2.8.0.RC3.

+3

Hãy nhìn vào http://stackoverflow.com/question/1052476/can-someone-explain-scalas-yield/1059501 # 1059501 và http://stackoverflow.com/questions/1721356/scala-2-8-canbuildfrom –

Trả lời

18

Cảm ơn michael.kebe vì bình luận của bạn.

This giải thích cách for được phiên dịch sang các hoạt động với map, flatMap, filterforeach. Vì vậy, ví dụ của tôi:

val s = for (i <- 0 to 9) yield math.random + i 

được phiên dịch sang một cái gì đó như thế này (tôi không chắc chắn nếu nó dịch sang map hoặc flatMap trong trường hợp này):

val s = (0 to 9) map { math.random + _ } 

Kiểu kết quả của các hoạt động như map trên bộ sưu tập phụ thuộc vào bộ sưu tập bạn gọi nó. Các loại 0 to 9 là một Range.Inclusive:

scala> val d = 0 to 9 
d: scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 

Kết quả của các hoạt động map trên đó là một IndexedSeq (vì những thứ người xây dựng bên trong thư viện các bộ sưu tập).

Vì vậy, để trả lời câu hỏi của tôi: kết quả của một for (...) yield ... phụ thuộc vào loại nào nằm bên trong các dấu ngoặc đơn. Nếu tôi muốn có một List như kết quả, tôi có thể làm điều này:

scala> val s = for (i <- List.range(0, 9)) yield math.random + i 
s: List[Double] = List(0.05778968639862214, 1.6758775042995566, ... 
+2

Nó được dịch sang bản đồ trong trường hợp của bạn. Nếu bạn có một hiểu cho hai máy phát điện, điều này được dịch sang một sự kết hợp flatMap/map. Vì vậy, cho (i <- 0 cho đến khi 9; j <- 0 cho đến i) năng suất (i * j) được dịch sang (0 đến 9) .flatMap {case i => (0 cho đến i) .map {case j => i * j}} –

+0

"phụ thuộc vào loại nào nằm bên trong các dấu ngoặc", chính xác hơn là thông số bên phải đầu tiên xác định loại. –

5

Bạn luôn có thể chuyển đổi hàng loạt vào một danh sách sử dụng ToList:

> val s = for (i <- (0 to 9).toList) yield math.random + i 
> s : List[Double] 
Các vấn đề liên quan