问题描述
这个 forEach
工作得很好
var newMarkers = new List<Marker>();
providers.forEach((p) {
var marker = markerFrom(p);
newMarkers.add(marker);
print("got one");
});
_markers = newMarkers;
但是这个 map
在与 forEach
放在完全相同的地方时永远不会被调用:
but this map
doesn't ever get called when placed in the exact same place as the 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;
}
推荐答案
Iterable
上的 map
函数是 lazy.它只是在原始 Iterable
周围创建了一个包装器,但在您开始迭代之前它实际上不会做任何事情.
The map
function on Iterable
is lazy. It just creates a wrapper around the original Iterable
, but it doesn't actually do anything until you start iterating.
这是一件好事,即使您已经习惯了其他语言的急切map
函数,这可能会令人惊讶.这意味着您可以在可迭代对象上组合操作,例如:
That's a good thing, even if it can be surprising if you are used to an eager map
function from other languages. It means that you can combine operations on iterables like:
listOfStrings
.map((x) => complicatedOperationOnString(x))
.take(2)
.forEach(print);
这里只对前两个字符串做复杂的操作.
This only does the complicated operation on the first two strings.
如果你想要一个标记列表,你需要在map
之后调用toList
:
If you want a list of the markers, you need to call toList
after the map
:
_markers = providers.map(markerFrom).toList();
通常,当传递给 map
的函数具有您希望只发生一次的副作用时,您应该非常小心.如果你多次迭代 map
的结果,每次都会发生这种效果,所以如果你这样做了:
In general, you should be very careful when the function passed to map
has side-effects that you want to only happen once. If you iterate the result of map
more than once, that effect will happen each time, so if you did:
_markers = providers.map(markerFrom);
int count = _markers.length;
_markers.forEach((marker) { doSomething(marker); });
你会冒险副作用发生两次,一次是length
,一次是forEach
,它们都迭代_markers代码>.它并不总是发生(一些迭代器知道它们的
length
而不实际迭代),但这总是有风险的.在这些情况下,要么使用 forEach
如果副作用是你唯一追求的,要么立即执行 toList
以强制执行所有操作,然后只查看之后的结果列表.
you would risk the side effects happening twice, once for length
and once for forEach
, which both iterate _markers
.It doesn't always happen (some iterables know their length
without actually iterating), but it is always a risk. In those cases, either use forEach
if the side-effect is the only thing you are after, or do an immediate toList
to force all the operations, and then only look at the resulting list after that.
这篇关于为什么 map 不起作用而 foreach 起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!