参数类型“SomeType?”无法分配给参数类型“SomeType”

2023-11-30

尝试调用函数时出现错误:

参数类型“SomeType?”无法分配给参数类型“SomeType”

我该如何解决?


该错误表明您正在尝试传递具有可为空类型的变量(SomeType?) 作为函数的参数,该函数需要non-可为空的参数(SomeType).

您必须检查该变量不是null first.根据定义,可空类型可能具有以下值null。将其传递给不期望的函数null显然会很糟糕。先检查一下。例如:

import 'dart:math';

final random = Random();

class Foo {}

/// Randomly returns a [Foo] instance or `null`.
Foo? maybeGetFoo() => random.nextBool() ? Foo() : null;

void printFoo(Foo fooInstance) => print(fooInstance);

void main() {
  Foo? foo = maybeGetFoo();

  printFoo(foo); // ERROR: The argument type 'Foo?' can't be assigned to the parameter type 'Foo'

  if (foo != null) {
    printFoo(foo); // OK, `foo` is now provably known to be of type `Foo`.
  }
}

通过检查是否local foo变量是null, foo可以自动类型提升为不可空类型。

请注意,自动类型升级只能发生在local变量或者例如变量都是final和私人的。:

class Bar {
  Foo? foo;

  Bar(this.foo);

  void printMember() {
    if (foo != null) {
      printFoo(foo); // ERROR
    }
  }
}

要解决此问题,您必须使用中间局部变量(首选):

  void printMember() {
    // Shadow with a local variable to allow automatic type promotion to occur.
    final foo = this.foo;
    if (foo != null) {
      printFoo(foo); // OK, `foo` is now provably known to be of type `Foo`.
    }
  }

或者你必须显式强制转换为不可空类型:

  void printMember() {
    if (foo != null) {
      printFoo(foo!); // Compiles.
      printFoo(foo as Foo); // Compiles.
    }
  }

使用显式强制转换(无论是!或与as)通常应该是最后的手段。重要的是,只有当您已经确定该值不是时才使用它null;如果是null, then ! and as会抛出一个TypeError在运行时并且应该使你的程序崩溃。此外,出于同样的原因,非局部变量不会自动进行类型提升,使用显式强制转换不一定安全,尽管实际上对于非病态代码来说通常应该没问题。

另请注意,在一些不常见的情况下,即使是局部变量在检查后也可能仍可为空(例如,变量在检查后重新分配)。看https://dart.dev/tools/non-promotion-reasons.

I also strongly推荐阅读 Dart 的了解零安全性文章。

最后,这并不是真正特定于空安全的;转换自Foo? to Foo只是一种形式downcast、和(后缀除外!运算符),以上所有内容通常适用于向下转型。从基本类型(例如从Object or dynamic) 到派生类型也只会发生在局部变量或final,私有实例变量:

class Baz {
  Object maybeFoo;

  Baz(this.maybeFoo);
}

void main() {
  var baz = Baz(Foo());
  if (baz.maybeFoo is Foo) {
    printFoo(baz.maybeFoo); // ERROR

    printFoo(baz.maybeFoo as Foo); // Compiles.
  }

  final maybeFoo = baz.maybeFoo;
  if (maybeFoo is Foo) {
    printFoo(maybeFoo); // OK, `maybeFoo` is now provably known to be of type `Foo`.
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

参数类型“SomeType?”无法分配给参数类型“SomeType” 的相关文章

随机推荐