拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 dart错误地假设value可以为空

dart错误地假设value可以为空

白鹭 - 2022-01-24 2168 0 0

我有代码

if (WORDLIST[language]==null) throw new Exception("Invalid Language");
List<String> wordlist = WORDLIST[language];

编译器说

但是,在我的代码中不可能将语言设定为无效的值,并且为了安全起见,如果在未检查语言存在的情况下在某处呼叫它,则会引发例外。我怎样才能让编译器认识到这是有效的?

完整代码在这里(尽管后来添加了例外以尝试处理新编译器): https ://github.com/mctrivia/bip39-multi/blob/mctrivia-patch-1/lib/src/bip39_multi_base.dart#L80

uj5u.com热心网友回复:

Map.operator []回传一个可为空的型别,句点。编译器不知道WORDLIST[language]运行时会回传什么;它不知道WORDLIST不是Map每次operator []呼叫都回传不同值的某些实作。这也是为什么只能对区域变量进行型别提升的原因。

解决此问题的典型方法是:

  • 用于!强制结果不可为空:
    if (WORDLIST[language]==null) throw new Exception("Invalid Language");
    List<String> wordlist = WORDLIST[language]!;
    
  • 使用区域变量:
    var result = WORDLIST[language];
    if (result == null) throw new Exception("Invalid Language");
    List<String> wordlist = result;
    
    由于wordlist可能已经是一个区域变量,您也可以重新排序您的代码:
    List<String>? wordlist = result;
    if (wordlist == null) throw new Exception("Invalid Language");
    // wordlist is now type-promoted to be List<String>.
    

uj5u.com热心网友回复:

编译器不够聪明,无法提升通用表达式,只能提升区域变量。

当您撰写if (WORDLIST[language] == null) throw ...时,这实际上并没有使编译器变得更明智。下面的WORDLIST[language]表达式。[]它需要有关运算子实作的特定知识WORDLIST来保证每次使用相同的自变量呼叫它时回传相同的值。编译器不假定有这样的知识。

你应该做的是:

List<String>? wordlist = WORDLIST[language];
if (wordlist == null) {
  throw ArgumentError.value(language, "language", "Invalid language");
}
// use `wordlist` as `List<String>` here.

通过将值分配给区域变量,您允许 test throw 在以下(隐式 else 分支)代码中将该变量提升为不可为空。

uj5u.com热心网友回复:

提示编译器的一种方法是添加一个 else 子句,这样编译器就可以确定 else 分支只会在WORDLIST[language]!=null.

if (WORDLIST[language]==null) throw new Exception("Invalid Language");
else List<String> wordlist = WORDLIST[language];
标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *