2010-04-30 25 views
11

Scala có cung cấp lớp, tiện ích, cú pháp hoặc cơ chế khác để chuyển đổi (bằng cách gói) một Iterator với Iterable không?scala ngầm hoặc chuyển đổi rõ ràng từ iterator thành iterable

Ví dụ, tôi có một Iterator [Foo] và tôi cần một Iterable [Foo], vì vậy hiện tôi:

val foo1: Iterator[Foo] = .... 
val foo2: Iterable[Foo] = new Iterable[Foo] { 
    def elements = foo1 
} 

Điều này có vẻ xấu xí và không cần thiết. Một cách tốt hơn là gì?

+0

trùng lặp http://stackoverflow.com/questions/1072784/how-can-i-convert-a-java-iterable-to-a-scala-iterable – wheaties

+3

@wheaties đây không phải là một trùng lặp với câu hỏi đó. –

Trả lời

12

Iterator có phương thức toIterable trong Scala 2.8.0, nhưng không phải trong 2.7.7 trở xuống. Nó không tiềm ẩn, nhưng bạn có thể xác định chuyển đổi tiềm ẩn của riêng bạn nếu bạn cần.

7

Bạn nên rất cẩn thận về bao giờ ngầm chuyển đổi một Iterator thành một Iterable (Tôi thường sử dụng Iterator.toList - rõ ràng). Lý do cho điều này là, bằng cách chuyển kết quả vào một phương thức (hoặc hàm) mà mong đợi một Iterable, bạn mất quyền kiểm soát nó ở mức độ chương trình của bạn có thể bị hỏng. Dưới đây là một ví dụ:

def printTwice(itr : Iterable[String]) : Unit = { 
    itr.foreach(println(_)) 
    itr.foreach(println(_)) 
} 

Nếu một Iterator bằng cách nào đó mặc nhiên chuyển đổi thành một Iterable, điều gì sẽ sau đây sẽ in?

printTwice(Iterator.single("Hello")) 

Nó (dĩ nhiên) chỉ in Xin chào một lần. Rất gần đây, traitTraversableOnce đã được thêm vào thư viện bộ sưu tập, trong đó hợp nhất IteratorIterable. Theo tôi, đây có thể là một sai lầm.

sở thích cá nhân của tôi là sử dụng Iterator rõ ràng bất cứ nơi nào có thể và sau đó sử dụng List, Set hoặc IndexedSeq trực tiếp. Tôi đã tìm thấy rằng tôi hiếm khi có thể viết một phương pháp mà thực sự là bất khả tri của loại nó được thông qua. Một ví dụ:

def foo(trades: Iterable[Trade]) { 
    log.info("Processing %d trades", trades.toList.length) //hmmm, converted to a List 

    val shorts = trades.filter(_.side.isSellShort) 
    log.info("Found %d sell-short", shorts.toList.length) //hmmm, converted to a List again 

    //etc 
+4

Tôi -1'd bạn bởi vì tuyên bố của bạn "Nó sẽ (tất nhiên) chỉ in Xin chào một lần" là sai. 'ToIterable' của Scala bao bọc Iterator trong một Stream, đảm bảo rằng bạn có được các ngữ nghĩa lặp lại thích hợp. Điều này khiến cho câu trả lời của bạn không chính xác. –

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