_Map 不在 [Map, bool] 中。

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

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

问题

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

void main() {
  final type = [Map<String, String>, bool];
  final mapTest = {"A": "B"};
  if (type.contains(mapTest.runtimeType)) {
    print("是的");
  } else {
    print("不, ${mapTest.runtimeType} 不在 $type 中");
  }
  bool boobool = true;
  if (type.contains(boobool.runtimeType)) {
    print("是的, ${boobool.runtimeType}$type 中");
  } else {
    print("不, ${mapTest.runtimeType} 不在 $type 中");
  }
}

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

英文:

I need to do runtime type check.

void main() {
  final type = [Map&lt;String, String&gt;, bool];
  final mapTest = {&quot;A&quot;: &quot;B&quot;};
  if (type.contains(mapTest.runtimeType)) {
    print(&quot;yes&quot;);
  } else {
    print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  }
  bool boobool = true;
  if (type.contains(boobool.runtimeType)) {
    print(&quot;yes, ${boobool.runtimeType} is in $type&quot;);
  } else {
    print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  }
}

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

no, _Map&lt;String, String&gt; is not in {Map&lt;String, String&gt;, bool}
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 要求右操作数在静态上是已知的。

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

/// 在所有非`dynamic`对象上提供 [staticType] 获取器。
extension StaticTypeExtension<T> on T {
  /// 返回此对象的静态类型。
  ///
 /// 这可用于报告对象的静态类型(由于推断或处理泛型时可能不太明显),它可能与 [Object.runtimeType] 不同。
  Type get staticType => T;
}

void main() {
  final type = [Map<String, String>, bool];
  final mapTest = {"A": "B"};
  if (type.contains(mapTest.staticType)) {
    print("yes");
  } else {
    print("no, ${mapTest.staticType} is not in $type");
  }
  bool boobool = true;
  if (type.contains(boobool.staticType)) {
    print("yes, ${boobool.staticType} is in $type");
  } else {
    print("no, ${mapTest.staticType} is not in $type");
  }
}

这将打印:

yes
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:

/// Provides a [staticType] getter on all non-`dynamic` objects.
extension StaticTypeExtension&lt;T&gt; on T {
  /// Returns the static type of this object.
  ///
  /// This can be used to report the static type of an object (which might not
  /// always be obvious due to inference or when dealing with generics), which
  /// might be different from [Object.runtimeType].
  Type get staticType =&gt; T;
}

void main() {
  final type = [Map&lt;String, String&gt;, bool];
  final mapTest = {&quot;A&quot;: &quot;B&quot;};
  if (type.contains(mapTest.staticType)) {
    print(&quot;yes&quot;);
  } else {
    print(&quot;no, ${mapTest.staticType} is not in $type&quot;);
  }
  bool boobool = true;
  if (type.contains(boobool.staticType)) {
    print(&quot;yes, ${boobool.staticType} is in $type&quot;);
  } else {
    print(&quot;no, ${mapTest.staticType} is not in $type&quot;);
  }
}

which prints:

yes
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>

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

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.

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

答案3

得分: 0

Dart通过使用`_Map`类继承的`Map`类的构造函数创建`Map`,并且您直接在`type`中提到了`Map&lt;String, String&gt;`的类型。

因此,我建议您采用在变量`type`中创建`runtimeType`的方式。

```dart
void main() {
  final type = [{&quot;A&quot;: &quot;B&quot;} .runtimeType, bool];
  final mapTest = {&quot;A&quot;: &quot;B&quot;} as Map&lt;String, String&gt;;
  if (type.contains(mapTest.runtimeType)) {
    print(&quot;yes&quot;);
  } else {
    print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  }
  bool boobool = true;
  if (type.contains(boobool.runtimeType)) {
    print(&quot;yes, ${boobool.runtimeType} is in $type&quot;);
  } else {
    print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  }
}
英文:

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.

void main() {
  final type = [{&quot;A&quot;: &quot;B&quot;} .runtimeType, bool];
  final mapTest = {&quot;A&quot;: &quot;B&quot;} as Map&lt;String, String&gt;;
  if (type.contains(mapTest.runtimeType)) {
    print(&quot;yes&quot;);
  } else {
    print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  }
  bool boobool = true;
  if (type.contains(boobool.runtimeType)) {
    print(&quot;yes, ${boobool.runtimeType} is in $type&quot;);
  } else {
    print(&quot;no, ${mapTest.runtimeType} is not in $type&quot;);
  }
}

答案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:

确定