我已將我的專案升級為空安全,這有點令人困惑,因為如果我包裝成
if(someObject.field != null) {
doSomething(someObject.field); // error, can't assign String? to String
}
一個方法呼叫需要一個不可為空的屬性,而我試圖傳遞的變數是可以為空的,然后我得到一個型別錯誤,我無法為不可為空的型別分配一個可為空的值。
但是當我這樣做時
String? someObjectField = someObject!.field;
if(someObjectField != null) {
doSometing(someObjectField); // Can assign
}
它按預期作業。
doSomething = (String foo) {}
例如:
class Person {
final String name;
Person(this.name);
}
Function test = () {
Map<String, String?> pers = {
'name': 'John',
};
if(pers['name'] != null) {
Person(pers['name']); // Error, even if it will be never executed
Person(pers['name'] as String); // no error
Person(pers['name']!); // no error
}
};
如果我做這樣的事情:
if (widget.event != null && widget.event.featuredImage != null)
然后它在第二個陳述句中抱怨接收者 (widget.event) 可以為 null 并且我需要使用!,但是第二個陳述句不應該執行并且它不應該導致運行時例外。
所以我需要將其修改為:
if (widget.event != null && widget.event!.featuredImage != null)
但是當我嘗試在 Flutter 中使用嵌套小部件時,即使我使用ifas 包裝器,我仍然需要在!任何地方添加
Stack(
children: [
// Add Container with image only when event and futured image are not null
if (widget.event != null && widget.event!.featuredImage != null) ...[
Container(
height: 250,
decoration: BoxDecoration(
color: Colors.transparent,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(widget.event!.featuredImage!), // here i Need to use ! to satisfy the compiler
),
),
),
],
],
)
或者,我可以將變數提取到另一個變數中,String? image = widget.event!.featuredImage然后將if陳述句修改為if(image != null)并使用像NetworkImage(image)預期那樣作業的小部件。
與檢測我是否在上述條件中檢查 null 的 TypeScript 相比,這對我來說毫無意義。
長話短說,即使我檢查空值來呈現/不呈現組件,我仍然需要使用!.
有什么明顯的東西我失蹤了嗎?
先感謝您
uj5u.com熱心網友回復:
由于您將它與 TypeScript 進行了比較,是的,您錯過了一些東西。
打字稿是在非常有限的環境中作業的混亂,“作業”被嚴重夸大了。例如,您可以在打字稿中撰寫一個接受字串的方法,然后在運行時發現它實際上不是字串,令人驚訝的是,它是一種完全不同的型別。JavaScript 的樂趣。與 JS 相比,將 TypeScript 稱為“型別安全”是正確的,而與實際編譯的語言相比則是荒謬的。
所以你錯過了這樣一個事實,即 Dart 編譯器可以保證一旦你檢查它就不是空的。為此,它需要額外的約束。例如,您可能有每次呼叫 getter 時都不會回傳相同值的 getter。例如,您的呼叫很容易在第一次和第二次呼叫之間回傳不同的值,具體取決于 getter 的代碼。或者您可以使用繼承和多型來構建一些更有問題的結構。在這里看到一個有趣的例子。所以你需要有一個區域變數,它保證具有相同的值,除非明確改變。
您的示例if (widget.event != null && widget.event.featuredImage != null)可以輕松修改為:
final image = widget?.event?.featuredImage;
Stack(
children: [
// Add Container with image only when event and futured image are not null
if (image != null) ...[
Container(
height: 250,
decoration: BoxDecoration(
color: Colors.transparent,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(image),
),
),
),
],
],
)
是的,你必須實作邏輯的一些點點,你不能只是一巴掌?,并!在你的代碼,它作為前。但是一旦你理解了邏輯上的微小變化是什么,那就很容易了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/342565.html
