匹配的类型为`(String, int)?`的值不能分配给所需的类型`(Object?, Object?)`。

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

Dart nullable records with pattern matching: The matched value of type '(String, int)?' isn't assignable to the required type '(Object?, Object?)'

问题

(final String? word, final int? number) = getPair();
英文:

Given the following function:

(String, int)? getPair() {
  return ('hello', 42);
}

I can access the multiple returns using the fields like so:

final pair = getPair();
if (pair != null) {
  String word = pair.$1;
  int number = pair.$2;
}

However, I'd prefer to destructure the values using some sort of pattern matching. This is what I tried:

final (word, number) = getPair();

But that gives the following error:

> The matched value of type '(String, int)?' isn't assignable to the required type '(Object?, Object?)'.
> Try changing the required type of the pattern, or the matched value type.

How would I change the required type of the pattern or the matched value?

Related reference:

答案1

得分: 2

你可以对结果进行模式匹配并提取:

void main(List<String> arguments) {
  final (word, number) = switch (getPair()) {
    (String s, int i) => (s, i),
    final v => throw Exception('$v did not match'),
  };
  print('word is $word, number is $number');
}

(String, int)? getPair() {
  return ('hello', 42);
}

如果你需要变量在有限的范围内使用,你可以使用 if-case:

void main(List<String> arguments) {
  if (getPair() case (final String word, final int number)) {
    print('word is $word, number is $number');
  }
}

(String, int)? getPair() {
  return ('hello', 42);
}
英文:

You can pattern match on the result and extract with that:

void main(List&lt;String&gt; arguments) {
  final (word, number) = switch (getPair()) {
    (String s, int i) =&gt; (s, i),
    final v =&gt; throw Exception(&#39;$v did not match&#39;),
  };
  print(&#39;word is $word, number is $number&#39;);
}

(String, int)? getPair() {
  return (&#39;hello&#39;, 42);
}

If you need the vars for a limited scope, you can use if-case:

void main(List&lt;String&gt; arguments) {
  if (getPair() case (final String word, final int number)) {
    print(&#39;word is $word, number is $number&#39;);
  }
}

(String, int)? getPair() {
  return (&#39;hello&#39;, 42);
}

答案2

得分: 1

在`null`检查之后,你可以进行解构,就像你手动使用`$1`和`$2`一样:
```dart
final pair = getPair();
if (pair != null) {
  final (word, number) = pair;
  // ...
}

你可以将非null 断言 作为声明模式的一部分:

final ((word, number)!) = getPair();

如果值为null,将会抛出异常。

你不能在声明中进行null 检查,因为声明模式必须是不可反驳的,而检查可能失败。

你可以在可反驳模式检查的一部分中进行空检查,使用?

if (getPair() case (final word, final number)?) {
  // ...
} // else { &quot;or else, if needed&quot;; }

或者

switch (getPair()) {
  case (final word, final number)?: // ....
  // default: &quot;or else, if needed&quot;;
}

由于在后续解构中还匹配了类型,可以删除?

或者,如果你还想要绑定pair,你可以结合这两种方法:

if (getPair() case final pair?) { // 如果不为`null`,则绑定`pair`。
  final (word, number) = pair;
}
英文:

You can do that destructuring after the null-check, like you did manually using $1 and $2:

final pair = getPair();
if (pair != null) {
  final (word, number) = pair;
  // ...
}

You can do a not-null assert as part of a declaration pattern:

final ((word, number)!) = getPair();

That will throw if the value is null.

You cannot do a null check as part of a declaration, because declaration patterns must be irrefutable, and a check can fail.

You can do the null check as part of a refutable pattern check, using ?:

if (getPair() case (final word, final number)?) {
  // ...
} // else { &quot;or else, if needed&quot;; }

or

switch (getPair()) {
  case (final word, final number)?: // ....
  // default: &quot;or else, if needed&quot;;
}

Since you're then also matching the type in the following destructuring, the ? can be removed.

Or you can combine the two approaches, if you also want the binding of pair:

if (getPair() case final pair?) { // Bind `pair` if it&#39;s not `null`.
  final (word, number) = pair;
}

答案3

得分: 0

这是一个比我想要的更冗长一些的解决方案,但这是一个部分解决方案:

final pair = getPair();
if (pair == null) return; // or throw/break/continue
final (word, number) = pair;

如果有更直接的方法,我欢迎另一个答案。

英文:

Well, this is a little more verbose that what I was looking for, but this is a partial solution:

final pair = getPair();
if (pair == null) return; // or throw/break/continue
final (word, number) = pair;

I welcome another answer if there is a more direct way to do it.

huangapple
  • 本文由 发表于 2023年7月20日 08:55:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76726033.html
匿名

发表评论

匿名网友

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

确定