_Map 不在 [Map, bool] 中。

huangapple go评论170阅读模式
英文:

Why _Map<String, String> is not in [Map<String, String>, bool]

问题

我需要进行运行时类型检查。

  1. void main() {
  2. final type = [Map<String, String>, bool];
  3. final mapTest = {"A": "B"};
  4. if (type.contains(mapTest.runtimeType)) {
  5. print("是的");
  6. } else {
  7. print("不, ${mapTest.runtimeType} 不在 $type 中");
  8. }
  9. bool boobool = true;
  10. if (type.contains(boobool.runtimeType)) {
  11. print("是的, ${boobool.runtimeType}$type 中");
  12. } else {
  13. print("不, ${mapTest.runtimeType} 不在 $type 中");
  14. }
  15. }

mapTest 应该通过测试。但是它没有。有什么问题?

英文:

I need to do runtime type check.

  1. void main() {
  2. final type = [Map&lt;String, String&gt;, bool];
  3. final mapTest = {&quot;A&quot;: &quot;B&quot;};
  4. if (type.contains(mapTest.runtimeType)) {
  5. print(&quot;yes&quot;);
  6. } else {
  7. print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  8. }
  9. bool boobool = true;
  10. if (type.contains(boobool.runtimeType)) {
  11. print(&quot;yes, ${boobool.runtimeType} is in $type&quot;);
  12. } else {
  13. print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  14. }
  15. }

mapTest should pass the test. But it doesn't. What's wrong ?

  1. no, _Map&lt;String, String&gt; is not in {Map&lt;String, String&gt;, bool}
  2. yes, bool is in {Map&lt;String, String&gt;, bool}

答案1

得分: 1

  1. Map<K, V> 是一个抽象类型。任何对象都不可能具有 Map<K, V>runtimeType;任何对象都将是某个具体类型的实例。

  2. Type 对象通常仅在精确相同的 Type 时相等;它不会检查一个 Type 是否表示另一个的子类型。

因此,mapTest.runtimeType 不可能与 Map<K, V> 相等。

您也将无法使用 ismapTest is type[0] 是不合法的,因为 is 要求右操作数在静态上是已知的。

最好的做法是,在这种情况下,您可以检查静态类型而不是运行时类型:

  1. /// 在所有非`dynamic`对象上提供 [staticType] 获取器。
  2. extension StaticTypeExtension<T> on T {
  3. /// 返回此对象的静态类型。
  4. ///
  5. /// 这可用于报告对象的静态类型(由于推断或处理泛型时可能不太明显),它可能与 [Object.runtimeType] 不同。
  6. Type get staticType => T;
  7. }
  8. void main() {
  9. final type = [Map<String, String>, bool];
  10. final mapTest = {"A": "B"};
  11. if (type.contains(mapTest.staticType)) {
  12. print("yes");
  13. } else {
  14. print("no, ${mapTest.staticType} is not in $type");
  15. }
  16. bool boobool = true;
  17. if (type.contains(boobool.staticType)) {
  18. print("yes, ${boobool.staticType} is in $type");
  19. } else {
  20. print("no, ${mapTest.staticType} is not in $type");
  21. }
  22. }

这将打印:

  1. yes
  2. yes, bool is in [Map<String, String>, bool]

话虽如此,最终您想要做的事情可能相当值得质疑。依赖于特定的 Type 值通常不是一个好主意,因为如前所述,子类型不会自动处理。

英文:
  1. Map&lt;K, V&gt; is an abstract type. It is impossible for any object to have a runtimeType of Map&lt;K, V&gt;; any object will be an instance of some concrete type.
  2. Type objects usually are equal only for the exact same Type; it does not check if one Type represents a subtype of the other.

Consequently, it is impossible for mapTest.runtimeType to ever compare equal to Map&lt;K, V&gt;.

You also will not be able to use is; mapTest is type[0] is not legal since is requires that the right operand be statically known.

At best, for this case, you could check for static types instead of runtime types:

  1. /// Provides a [staticType] getter on all non-`dynamic` objects.
  2. extension StaticTypeExtension&lt;T&gt; on T {
  3. /// Returns the static type of this object.
  4. ///
  5. /// This can be used to report the static type of an object (which might not
  6. /// always be obvious due to inference or when dealing with generics), which
  7. /// might be different from [Object.runtimeType].
  8. Type get staticType =&gt; T;
  9. }
  10. void main() {
  11. final type = [Map&lt;String, String&gt;, bool];
  12. final mapTest = {&quot;A&quot;: &quot;B&quot;};
  13. if (type.contains(mapTest.staticType)) {
  14. print(&quot;yes&quot;);
  15. } else {
  16. print(&quot;no, ${mapTest.staticType} is not in $type&quot;);
  17. }
  18. bool boobool = true;
  19. if (type.contains(boobool.staticType)) {
  20. print(&quot;yes, ${boobool.staticType} is in $type&quot;);
  21. } else {
  22. print(&quot;no, ${mapTest.staticType} is not in $type&quot;);
  23. }
  24. }

which prints:

  1. yes
  2. yes, bool is in [Map&lt;String, String&gt;, bool]

That said, whatever it is you ultimately want to do with this is probably pretty questionable. It's usually not a good idea to rely on specific Type values because, as mentioned, subtypes won't be automatically handled.

答案2

得分: 0

因为 mapTest 的运行时类型是 _InternalLinkedHashMap<String, String>,与 Map<String, String> 不同,所以未通过类型检查。

为了通过类型检查,你可以考虑将 mapTest 显式转换为 Map<String, String>

  1. final type = [Map<String, String>, bool];
  2. final mapTest = {"A": "B"};
  3. if (type.contains(mapTest.runtimeType) || type.contains(mapTest.runtimeType.toString())) {
  4. print("yes");
  5. } else if (mapTest is Map<String, String> && type.contains(Map<String, String>)) {
  6. print("yes, ${mapTest.runtimeType} is in $type");
  7. } else {
  8. print("no, ${mapTest.runtimeType} is not in $type");
  9. }
英文:

It is because mapTest&#39;s runtime type is _InternalLinkedHashMap&lt;String, String&gt;, which is different from Map&lt;String, String&gt; so it fails the type check.

To make the type check pass, you can consider converting the mapTest to Map&lt;String,String explicitly.

  1. final type = [Map&lt;String, String&gt;, bool];
  2. final mapTest = {&quot;A&quot;: &quot;B&quot;};
  3. if (type.contains(mapTest.runtimeType) || type.contains(mapTest.runtimeType.toString())) {
  4. print(&quot;yes&quot;);
  5. } else if (mapTest is Map&lt;String, String&gt; &amp;&amp; type.contains(Map&lt;String, String&gt;)) {
  6. print(&quot;yes, ${mapTest.runtimeType} is in $type&quot;);
  7. } else {
  8. print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  9. }

答案3

得分: 0

  1. Dart通过使用`_Map`类继承的`Map`类的构造函数创建`Map`,并且您直接在`type`中提到了`Map&lt;String, String&gt;`的类型。
  2. 因此,我建议您采用在变量`type`中创建`runtimeType`的方式。
  3. ```dart
  4. void main() {
  5. final type = [{&quot;A&quot;: &quot;B&quot;} .runtimeType, bool];
  6. final mapTest = {&quot;A&quot;: &quot;B&quot;} as Map&lt;String, String&gt;;
  7. if (type.contains(mapTest.runtimeType)) {
  8. print(&quot;yes&quot;);
  9. } else {
  10. print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  11. }
  12. bool boobool = true;
  13. if (type.contains(boobool.runtimeType)) {
  14. print(&quot;yes, ${boobool.runtimeType} is in $type&quot;);
  15. } else {
  16. print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  17. }
  18. }
英文:

Dart create a Map by using constructor of _Map which inherited by class Map, and you directly mentioned type of Map&lt;String, String&gt; in in type.

So I suggest you to go with the way of creating a runtimeType in a variable type.

  1. void main() {
  2. final type = [{&quot;A&quot;: &quot;B&quot;} .runtimeType, bool];
  3. final mapTest = {&quot;A&quot;: &quot;B&quot;} as Map&lt;String, String&gt;;
  4. if (type.contains(mapTest.runtimeType)) {
  5. print(&quot;yes&quot;);
  6. } else {
  7. print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  8. }
  9. bool boobool = true;
  10. if (type.contains(boobool.runtimeType)) {
  11. print(&quot;yes, ${boobool.runtimeType} is in $type&quot;);
  12. } else {
  13. print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  14. }
  15. }

答案4

得分: 0

将以下内容翻译为中文:

各种答案,但我找到了最简单的解决方案。

final type = [Map&lt;String, String&gt;, bool];

改为

final type = [Map&lt;String, String&gt;().runtimeType, bool];

似乎实现了预期目的。

是的,_Map&lt;String, String&gt; 在 [_Map&lt;String, String&gt;, bool, List&lt;String&gt;] 中。

英文:

Various answers but I found the simplest solution.

Change

final type = [Map&lt;String, String&gt;, bool];

to

final type = [Map&lt;String, String&gt;().runtimeType, bool];

It seems to fulfill the purpose

yes, _Map&lt;String, String&gt; is in [_Map&lt;String, String&gt;, bool, List&lt;String&gt;]

huangapple
  • 本文由 发表于 2023年3月9日 12:58:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75680580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定