给定一个Map
变量,我如何从它确定键和值的类型?
例如:
void doSomething(Map m){
print('m: ${m.runtimeType}');
print('keys: ${m.keys.runtimeType}');
print('values: ${m.values.runtimeType}');
print('entries: ${m.entries.runtimeType}');
}
void main() async {
Map<String, int> m = {};
doSomething(m);
}
打印
m: _InternalLinkedHashMap<String, int>
keys: _CompactIterable<String>
values: _CompactIterable<int>
entries: MappedIterable<String, MapEntry<String, int>>
但是我怎样才能得到键和值的实际类型(即String
和int
),以便我可以在类型检查代码(即if( KeyType == String )
)中使用它们?
如果一个类没有提供类型参数,则不能提取该类的类型参数,而Map
没有。
一个提供它们的类的例子是:
class Example<T> {
Type get type => T;
R withType<R>(R Function<X>() callback) => callback<T>();
}
如果你有一个Example
的实例,你可以得到类型参数,或者作为Type
(这通常是无用的),或者作为类型参数,允许你对类型做任何事情。
唉,在大多数类中,以这种方式提供对类型变量的访问是非常罕见的。
你可以使用反射,如果你有访问dart:mirrors
,但大多数代码不(它不工作与提前编译,包括所有的web代码,或在Flutter程序)。
您可以尝试通过尝试您知道的类型(例如map is Map<dynamic, num>
,然后map is Map<dynamic, int>
和map is Map<dynamic, Never>
)来猜测类型。如果前两个为真,最后一个为假,则值类型肯定是int
。只有当你知道所有可能的类型时,这才有效。对于int
和String
这样的平台类型,它确实工作得特别好,因为您可以确定它们唯一的子类型是Never
。
如果您可以依赖静态类型而不是运行时类型,则可以使用泛型函数:
Type mapKeyType<K, V>(Map<K, V> map) => K;
否则,您需要有一个非空的Map
,并检查实际元素的运行时类型。