我有代碼
if (WORDLIST[language]==null) throw new Exception("Invalid Language");
List<String> wordlist = WORDLIST[language];
編譯器說
錯誤:“串列?”型別的值 不能分配給“串列”型別的變數,因為“串列?” 可以為空,而 'List' 不是。
但是,在我的代碼中不可能將語言設定為無效的值,并且為了安全起見,如果在未檢查語言存在的情況下在某處呼叫它,則會引發例外。我怎樣才能讓編譯器認識到這是有效的?
完整代碼在這里(盡管后來添加了例外以嘗試處理新編譯器): 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];
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/409976.html
標籤:
