ไม่เป็นโมฆะ (โดยค่าเริ่มต้น)
ไม่ใช่ nullable (ค่าเริ่มต้น) การทดสอบปัจจุบันสามารถพบได้ที่nullsafety.dartpad.dev
โปรดทราบว่าคุณสามารถอ่านข้อมูลจำเพาะเต็มได้ที่นี่และแผนงานเต็มได้ที่นี่
ค่าเริ่มต้นที่ไม่เป็นโมฆะหมายถึงอะไร
void main() {
String word;
print(word); // illegal
word = 'Hello, ';
print(word); // legal
}
ดังที่คุณเห็นด้านบนตัวแปรที่ไม่เป็นโมฆะโดยค่าเริ่มต้นหมายความว่าตัวแปรทุกตัวที่ประกาศตามปกติไม่สามารถเป็นnull
ได้ ดังนั้นการดำเนินการใด ๆ ที่เข้าถึงตัวแปรก่อนที่จะได้รับมอบหมายนั้นผิดกฎหมาย
นอกจากnull
นี้ไม่อนุญาตให้กำหนดตัวแปรที่ไม่ใช่ค่า nullable:
void main() {
String word;
word = null; // forbidden
world = 'World!'; // allowed
}
สิ่งนี้จะช่วยฉันได้อย่างไร
หากตัวแปรไม่สามารถลบล้างได้คุณสามารถมั่นใจได้ว่ามันจะไม่มีวันnull
เปลี่ยนแปลง ด้วยเหตุนี้คุณจึงไม่จำเป็นต้องตรวจสอบล่วงหน้า
int number = 4;
void main() {
if (number == null) return; // redundant
int sum = number + 2; // allowed because number is also non-nullable
}
จำ
ฟิลด์อินสแตนซ์ในคลาสต้องเริ่มต้นถ้าฟิลด์นั้นไม่สามารถ null ได้:
class Foo {
String word; // forbidden
String sentence = 'Hello, World!'; // allowed
}
ดูlate
ด้านล่างเพื่อปรับเปลี่ยนพฤติกรรมนี้
ประเภทที่มีค่าเป็นโมฆะ ( ?
)
คุณสามารถใช้ประเภท nullableโดยผนวกเครื่องหมายคำถาม?
กับประเภทตัวแปร:
class Foo {
String word; // forbidden
String? sentence; // allowed
}
nullableตัวแปรไม่ต้องมีการเริ่มต้นก่อนที่จะสามารถนำมาใช้ มันถูกเริ่มต้นnull
ตามค่าเริ่มต้น:
void main() {
String? word;
print(word); // prints null
}
!
ผนวก!
กับตัวแปรใดe
จะโยนข้อผิดพลาด runtimeถ้าe
เป็นโมฆะและอื่น ๆ แปลงเป็นไม่ใช่ nullablev
ค่า
void main() {
int? e = 5;
int v = e!; // v is non-nullable; would throw an error if e were null
String? word;
print(word!); // throws runtime error if word is null
print(null!); // throws runtime error
}
late
คำหลักlate
สามารถใช้เพื่อทำเครื่องหมายตัวแปรที่จะเริ่มต้นในภายหลังเช่นไม่ใช่เมื่อมีการประกาศ แต่เมื่อมีการเข้าถึง นอกจากนี้ยังหมายความว่าเราสามารถมีฟิลด์อินสแตนซ์ที่ไม่เป็นโมฆะซึ่งจะเริ่มต้นได้ในภายหลัง:
class ExampleState extends State {
late String word; // non-nullable
@override
void initState() {
super.initState();
// print(word) here would throw a runtime error
word = 'Hello';
}
}
การเข้าถึงword
ก่อนที่จะเริ่มต้นจะทำให้เกิดข้อผิดพลาดรันไทม์
late final
ตัวแปรสุดท้ายสามารถทำเครื่องหมายได้ช้ากว่านี้:
late final int x = heavyComputation();
ที่นี่heavyComputation
จะถูกเรียกเพียงครั้งเดียวเท่านั้นที่มีการx
เข้าถึง นอกจากนี้คุณยังสามารถประกาศแบบlate final
ไม่มี initializer ซึ่งเหมือนกับการมีเพียงlate
ตัวแปร แต่สามารถกำหนดได้เพียงครั้งเดียวเท่านั้น
late final int x;
// w/e
x = 5; // allowed
x = 6; // forbidden
โปรดทราบว่าขณะนี้ตัวแปรระดับบนสุดหรือแบบสแตติกที่มี initializer จะได้รับการประเมินlate
ไม่ว่าจะเป็นfinal
ก็ตาม
required
ก่อนหน้านี้มีคำอธิบายประกอบ ( @required
) ตอนนี้ในตัวเป็นตัวดัดแปลง อนุญาตให้ทำเครื่องหมายพารามิเตอร์ที่ตั้งชื่อใด ๆ (สำหรับฟังก์ชั่นหรือคลาส) เป็นrequired
ซึ่งทำให้พวกเขาไม่เป็นโมฆะ:
void allowed({required String word}) => null;
นี่หมายความว่าหากพารามิเตอร์ควรไม่เป็นโมฆะก็จำเป็นต้องทำเครื่องหมายเป็นrequired
หรือมีค่าเริ่มต้น:
void allowed({String word = 'World'}) => null;
void forbidden({int x}) // compile-time error because x can be null (unassigned)
=>
null;
พารามิเตอร์ที่มีชื่ออื่นใดจะต้องเป็นโมฆะ :
void baz({int? x}) => null;
?[]
ตัวดำเนินการ null ที่ทราบ?[]
ถูกเพิ่มสำหรับตัวดำเนินการดัชนี[]
:
void main() {
List<int>? list = [1, 2, 3];
int? x = list?[0]; // 1
}
ดูยังบทความนี้เกี่ยวกับการตัดสินใจไวยากรณ์
?..
ผู้ประกอบการน้ำตกในขณะนี้นอกจากนี้ยังมีผู้ประกอบการตระหนักถึง null ?..
ใหม่:
มันทำให้เกิดการดำเนินงานที่น้ำตกดังต่อไปนี้เท่านั้นที่สามารถดำเนินการถ้าผู้รับเป็นไม่เป็นโมฆะ ดังนั้น, ?..
จะต้องเป็นตัวดำเนินการเรียงซ้อนแรกในลำดับเรียงซ้อน:
void main() {
Path? path;
// Will not do anything if path is null.
path
?..moveTo(3, 4)
..lineTo(4, 3);
// This is a noop.
(null as List)
?..add(4)
..add(2)
..add(0);
}
Never
เพื่อหลีกเลี่ยงความสับสน: นี่ไม่ใช่สิ่งที่นักพัฒนาต้องกังวล ฉันต้องการพูดถึงมันเพื่อความสมบูรณ์
Never
เป็นไปได้ชนิดเช่นที่มีอยู่ก่อนหน้านี้Null
( ไม่null
) dart:core
ที่กำหนดไว้ใน ทั้งสองคลาสนี้ไม่สามารถขยายนำไปใช้หรือผสมกันได้ดังนั้นจึงไม่ต้องการใช้
เป็นหลักNever
หมายความว่าไม่อนุญาตให้ใช้ประเภทและNever
ไม่สามารถสร้างอินสแตนซ์ได้
แต่ไม่มีอะไรNever
ใน List<Never>
ความพึงพอใจข้อ จำกัด ประเภททั่วไปของรายการซึ่งหมายความว่ามันจะต้องมีที่ว่างเปล่า List<Null>
อย่างไรก็ตามสามารถมีnull
:
// Only valid state: []
final neverList = <Never>[
// Any value but Never here will be an error.
5, // error
null, // error
Never, // not a value (compile-time error)
];
// Can contain null: [null]
final nullList = <Null>[
// Any value but Null will be an error.
5, // error
null, // allowed
Never, // not a value (compile-time error)
Null, // not a value (compile-time error)
];
ตัวอย่าง: เรียบเรียงจะอนุมานList<Never>
สำหรับที่ว่างเปล่า ไม่ควรถูกใช้โดยโปรแกรมเมอร์เท่าที่ฉันกังวลconst List<T>
Never
Never
สามารถใช้งานได้หรือไม่?