Iterable.map<T> https://api.dartlang.org/stable/2.1.0/dart-core/Iterable/map.html:
map<T>(T f(E e)) → Iterable<T>
返回一个新的惰性 Iterable,其中包含通过调用创建的元素
f 按迭代顺序在此 Iterable 的每个元素上。 [...]
-
T
是一种语言Type
在这种情况下,可迭代项的类型也是该函数的类型f
必须返回。
-
→
告诉你return type
整个函数(map
)在这种情况下Iterable
of T
-
f
是应用到的函数Element e
作为参数传递给函数,以便函数可以对当前值执行一些操作,然后返回类型的新值T
基于元素的值e
.
如果你导航 Iterablemap函数定义 https://api.dartlang.org/stable/2.1.0/dart-core/Iterable/map.html你会看到:
Iterable<T> map <T>(
T f(
E e
)
)
所以我想从确切的开始来提高我的答案map<T>
OP 的功能,然后切换到更复杂的示例。
为了澄清所有这些,让我们看一个 Iterable 类的具体类,Set https://api.dartlang.org/stable/2.1.0/dart-core/Set-class.html班级选择一个Set
类型的String
在这种情况下:
Set<String> mySet = Set();
for (int i=0; i++<5;) {
mySet.add(i.toString());
}
var myNewSet = mySet.map((currentValue) => (return "new" + currentValue));
for (var newValue in myNewSet) {
debugPrint(newValue);
}
这里我有一个字符串集 Set<String>
我想要另一个字符串集 Set<String>
以便该值与原始地图的值相同,但带有前缀"new:"
。为此我们可以轻松地使用map<T>
连同它想要作为参数的闭包。
作为闭包传递的函数是
(currentValue) => ("new:" + currentValue)
如果我们愿意,我们也可以这样写:
(currentValue) {
return "new:" + currentValue;
}
甚至传递这样的函数:
String modifySetElement(String currentValue) {
return "new:" + currentValue;
}
var myNewSet = mySet.map((value) => ("new:" + value));
var myNewSet = mySet.map((value) {return "new:" + value;});
var myNewSet = mySet.map((value) => modifySetElement("new:" + value));
这意味着函数(闭包)的参数是String
value of the element E
of the Set
我们正在修改。
我们甚至不必指定类型,因为它是通过方法定义推断的,这是泛型的强大功能之一。
函数(闭包)将一次应用于 Set 的所有元素,但您将其编写为闭包一次。
所以总结一下:
-
T
是字符串
-
E
是我们在函数内部处理的元素
-
f
是我们的结束
让我们通过一个更复杂的示例来更深入地了解一下。我们现在要处理的是Dart Map https://api.dartlang.org/stable/2.1.0/dart-core/Map-class.html class.
Its map https://api.dartlang.org/stable/2.1.0/dart-core/Map/map.html函数的定义如下:
map<K2, V2>(MapEntry<K2, V2> f(K key, V value)) → Map<K2, V2>
所以在这种情况下,前面的第一和第三T
is (K2, V2)
以及函数的返回类型f
(闭包),作为元素E
参数对K
and V
(这是当前的键和值MapEntry
迭代的元素),是一种类型MapEntry<K2, V2>
是前一秒T
.
然后整个函数返回一个新的Map<K2, V2>
下面是一个实际的例子Map
:
Map<int, String> myMap = Map();
for (int i=0; i++<5;) {
myMap[i] = i.toString();
}
var myNewMap = myMap.map((key, value) => (MapEntry(key, "new:" + value)));
for (var mapNewEntry in myNewMap.entries) {
debugPrint(mapNewEntry.value);
}
在这个例子中我有一个Map<int, String>
我想要另一个Map<int, String>
所以(像以前一样)该值与原始地图的值相同,但带有前缀"new:"
.
同样,您可以编写闭包(您的f
函数)也是这样(也许它更好地强调了一个事实,即它是一个基于当前地图条目值创建全新地图条目的函数)。
var myNewMap = myMap.map((key, value) {
String newString = "new:" + value;
return MapEntry(key, newString);
});
所有这些符号被称为Generics https://www.dartlang.org/guides/language/language-tour#generics因为它们是通用占位符,根据您使用它们的上下文对应于一种类型或另一种类型。
这是上面链接的摘录:
使用通用方法
最初,Dart 的通用支持仅限于类。一种称为泛型方法的新语法允许
方法和函数的类型参数:
T first<T>(List<T> ts) {
// Do some initial work or error checking, then...
T tmp = ts[0];
// Do some additional checking or processing...
return tmp;
}
这里,first() 上的泛型类型参数允许您使用
在几个地方输入参数 T:
在函数的返回类型中(T
)。在参数类型中
(List<T>
)。在局部变量的类型中(T tmp
).
按照这个link https://www.dartlang.org/guides/language/effective-dart/design#do-follow-existing-mnemonic-conventions-when-naming-type-parameters对于泛型名称约定。