Non-nullable (secara default)
Eksperimen yang tidak dapat dibatalkan (secara default) saat ini dapat ditemukan di nullsafety.dartpad.dev .
Ingatlah bahwa Anda dapat membaca spesifikasi lengkap di sini dan peta jalan lengkap di sini .
Apa yang dimaksud dengan non-nullable secara default?
void main() {
String word;
print(word); // illegal
word = 'Hello, ';
print(word); // legal
}
Seperti yang Anda lihat di atas, variabel yang tidak dapat dibatalkan secara default berarti bahwa setiap variabel yang dideklarasikan secara normal tidak dapat null. Akibatnya, setiap operasi yang mengakses variabel sebelum ditugaskan adalah ilegal.
Selain itu, penetapan nullke variabel yang tidak dapat dibatalkan juga tidak diizinkan:
void main() {
String word;
word = null; // forbidden
world = 'World!'; // allowed
}
Bagaimana ini membantu saya?
Jika suatu variabel tidak dapat dibatalkan , Anda dapat memastikan bahwa itu tidak pernah null. Karena itu, Anda tidak perlu memeriksanya sebelumnya.
int number = 4;
void main() {
if (number == null) return; // redundant
int sum = number + 2; // allowed because number is also non-nullable
}
Ingat
Bidang instance dalam kelas harus diinisialisasi jika tidak dapat dibatalkan:
class Foo {
String word; // forbidden
String sentence = 'Hello, World!'; // allowed
}
Lihat di latebawah untuk mengubah perilaku ini.
Jenis tidak dapat dihapus ( ?)
Anda dapat menggunakan jenis yang dapat dibatalkan dengan menambahkan tanda tanya ?ke jenis variabel:
class Foo {
String word; // forbidden
String? sentence; // allowed
}
Sebuah nullable variabel tidak perlu diinisialisasi sebelum dapat digunakan. Ini diinisialisasi sebagai nulldefault:
void main() {
String? word;
print(word); // prints null
}
!
Menambahkan !untuk setiap variabel eakan melempar kesalahan runtime jika enull dan sebaliknya mengubahnya menjadi non-nullable nilai v.
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
Kata kunci latedapat digunakan untuk menandai variabel yang akan diinisialisasi nanti , yaitu tidak ketika mereka dideklarasikan tetapi ketika mereka diakses. Ini juga berarti bahwa kita dapat memiliki bidang instance yang tidak dapat dibatalkan yang diinisialisasi nanti:
class ExampleState extends State {
late String word; // non-nullable
@override
void initState() {
super.initState();
// print(word) here would throw a runtime error
word = 'Hello';
}
}
Mengakses wordsebelum diinisialisasi akan menimbulkan kesalahan runtime.
late final
Variabel akhir sekarang juga dapat ditandai terlambat:
late final int x = heavyComputation();
Di sini heavyComputationhanya akan disebut sekali xdiakses. Selain itu, Anda juga dapat mendeklarasikan late finaltanpa penginisialisasi, yang sama dengan hanya memiliki latevariabel, tetapi hanya dapat ditugaskan satu kali.
late final int x;
// w/e
x = 5; // allowed
x = 6; // forbidden
Perhatikan bahwa semua variabel tingkat atas atau statis dengan penginisialisasi sekarang akan dievaluasi late, tidak peduli apakah itu variabel final.
required
Dahulu anotasi ( @required), sekarang sudah ada sebagai modifier. Ini memungkinkan untuk menandai parameter apa pun yang dinamai (untuk fungsi atau kelas) sebagai required, yang membuatnya tidak dapat dibatalkan:
void allowed({required String word}) => null;
Ini juga berarti bahwa jika suatu parameter tidak dapat dibatalkan , parameter tersebut harus ditandai sebagai requiredatau memiliki nilai default:
void allowed({String word = 'World'}) => null;
void forbidden({int x}) // compile-time error because x can be null (unassigned)
=>
null;
Parameter bernama lainnya harus nullable :
void baz({int? x}) => null;
?[]
Operator nol sadar ?[]telah ditambahkan untuk operator indeks []:
void main() {
List<int>? list = [1, 2, 3];
int? x = list?[0]; // 1
}
Lihat juga artikel ini tentang keputusan sintaksis .
?..
Operator cascade kini juga memiliki operator menyadari nol baru: ?...
Ini menyebabkan operasi kaskade berikut hanya dijalankan jika penerima tidak nol . Oleh karena itu, ?..harus menjadi operator kaskade pertama dalam urutan kaskade:
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
Untuk menghindari kebingungan: ini bukan sesuatu yang harus dikhawatirkan oleh pengembang. Saya ingin menyebutkannya demi kelengkapan.
Neverakan menjadi tipe seperti yang sudah ada sebelumnya Null( tidaknull ) didefinisikan dalam dart:core. Kedua kelas ini tidak dapat diperpanjang, diimplementasikan, atau dicampur, sehingga tidak dimaksudkan untuk digunakan.
Pada dasarnya, Neverberarti tidak ada tipe yang diizinkan dan Neveritu sendiri tidak dapat dipakai.
Tidak ada Neveryang List<Never>memuaskan batasan tipe generik dari daftar, yang berarti harus kosong . List<Null>Namun, dapat mengandung 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)
];
Contoh: kompiler akan menyimpulkan List<Never>untuk kosong const List<T> .
Nevertidak seharusnya digunakan oleh programmer sejauh yang saya ketahui.
Neverdapat digunakan?