此forEach
工作得很好
var newMarkers = new List<Marker>();
providers.forEach((p) {
var marker = markerFrom(p);
newMarkers.add(marker);
print("got one");
});
_markers = newMarkers;
但是当map
置于与forEach
完全相同的地方时,_markers = providers.map((p) => markerFrom(p));
无法被调用:
markerFrom
此外,这是 Marker markerFrom(FoodProvider provider) {
var marker = new Marker(new MarkerOptions()
..map = _map
..position = new LatLng(provider.latitude, provider.longitude)
..title = provider.name
..icon = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'
);
var infoWindow = new InfoWindow(new InfoWindowOptions()..content = marker.title);
marker.onClick.listen((e) {
infoWindow.open(_map, marker);
});
return marker;
}
方法:
window.focus
答案 0 :(得分:5)
map
上的Iterable
功能 lazy 。它只是在原始Iterable
周围创建一个包装器,但在开始迭代之前它实际上没有做任何事情。
这是一个好东西,即使你习惯于使用其他语言的热切map
函数也会感到惊讶。这意味着您可以将操作组合在迭代物上,如:
listOfStrings
.map((x) => complicatedOperationOnString(x))
.take(2)
.forEach(print);
这只对前两个字符串进行了复杂的操作。
如果您需要标记列表,则需要在toList
之后调用map
:
_markers = providers.map(markerFrom).toList();
一般情况下,当传递给map
的函数具有您想要只发生一次的副作用时,您应该非常小心。如果您多次迭代map
的结果,那么每次都会发生这种效果,所以如果您这样做了:
_markers = providers.map(markerFrom);
int count = _markers.length;
_markers.forEach((marker) { doSomething(marker); });
您将冒险两次发生的副作用,一次针对length
,一次针对forEach
,两者都会重复_markers
。
它并不总是会发生(有些迭代物在没有实际迭代的情况下知道它们的length
),但它总是存在风险。在这些情况下,如果副作用是您唯一的事情,请使用forEach
,或立即toList
强制执行所有操作,然后仅查看结果列表。