为什么地图不起作用,而foreach却起作用? [英] Why is map not working but foreach is?
问题描述
此 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.
这篇关于为什么地图不起作用,而foreach却起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!