問題描述
我閱讀了 為什么 Java 的 Iterator 不是 Iterable? 和為什么枚舉不能迭代?,但我還是不明白為什么會這樣:
I read Why is Java's Iterator not an Iterable? and Why aren't Enumerations Iterable?, but I still don't understand why this:
void foo(Iterator<X> it) {
for (X x : it) {
bar(x);
baz(x);
}
}
無法實現.換句話說,除非我遺漏了什么,否則上述內容可能是很好且有效的語法糖:
was not made possible. In other words, unless I'm missing something, the above could have been nice and valid syntactic sugar for:
void foo(Iterator<X> it) {
for (X x; it.hasNext();) {
x = it.next();
bar(x);
baz(x);
}
}
推薦答案
但我仍然不明白為什么這個 [...] 無法實現.
我可以看到幾個原因:
Iterator
不可重用,因此 for/each 會消耗迭代器 - 也許不是不正確的行為,但對于那些不知道如何減少 for/each 糖分的人來說是不直觀的.Iterator
不會經常在代碼中裸露",因此這會使 JLS 變得復雜而收益甚微(for/each 結構本身就已經夠糟糕了,兩者都適用Iterable
s 和數組).- 有一個簡單的解決方法.僅僅為此分配一個新對象似乎有點浪費,但是分配很便宜,并且在大多數情況下,逃逸分析甚至可以消除您的小成本.(不過,為什么他們沒有在
Iterables
實用程序類中包含這種解決方法,類似于Collections
和Arrays
,我無法理解.) - (可能不是真的 - 請參閱評論.)
我似乎記得 JLS 只能引用java.lang
[需要引用] 中的內容,所以他們必須在java.lang
中創建一個Iterator
接口,該接口java.util.Iterator
擴展而不添加任何內容.現在我們有兩個功能等效的迭代器接口.50% 使用裸迭代器的新代碼將選擇java.lang
版本,其余使用java.util
中的版本.隨之而來的是混亂,兼容性問題比比皆是,等等.
Iterator
s are not reusable, so a for/each would consume the iterator - not incorrect behavior, perhaps, but unintuitive to those who don't know how the for/each is desugared.Iterator
s don't appear "naked" in code all that often so it would be complicating the JLS with little gain (the for/each construct is bad enough as it is, working on bothIterable
s and arrays).- There's an easy workaround. It may seem a little wasteful to allocate a new object just for this, but allocation is cheap as it is and escape analysis would rid you even of that small cost in most cases. (Why they didn't include this workaround in an
Iterables
utility class, analogous toCollections
andArrays
, is beyond me, though.) - (Probably not true - see the comments.)
I seem to recall that the JLS can only reference things injava.lang
[citation needed], so they'd have to create anIterator
interface injava.lang
whichjava.util.Iterator
extends without adding anything to. Now we have two functionally equivalent iterator interfaces. 50% of the new code using naked iterators will choose thejava.lang
version, the rest use the one injava.util
. Chaos ensues, compatibility problems abound, etc.
我認為第 1-3 點非常符合 Java 語言設計理念的走向:不要讓新手感到驚訝,如果沒有明顯的收益超過成本,不要使規范復雜化, 不要用語言特性來做圖書館可以做的事情.
I think points 1-3 are very much in line with how the Java language design philosophy seems to go: Don't surprise newcomers, don't complicate the spec if it doesn't have a clear gain that overshadows the costs, and don't do with a language feature what can be done with a library.
同樣的論點可以解釋為什么 java.util.Enumeration
也不是 Iterable
.
The same arguments would explain why java.util.Enumeration
isn't Iterable
, too.
這篇關于Java:為什么不能迭代迭代器?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!