diff --git a/src/content/null-safety/understanding-null-safety.md b/src/content/null-safety/understanding-null-safety.md index 708241d464..e042445f16 100644 --- a/src/content/null-safety/understanding-null-safety.md +++ b/src/content/null-safety/understanding-null-safety.md @@ -1,6 +1,7 @@ --- title: Understanding null safety -description: A deep dive into Dart language and library changes related to null safety. +description: >- + A deep dive into Dart language and library changes related to null safety. --- _Written by Bob Nystrom
@@ -20,7 +21,7 @@ problem.][billion] Here is an example: // Without null safety: bool isEmpty(String string) => string.length == 0; -main() { +void main() { isEmpty(null); } ``` @@ -69,14 +70,14 @@ pros and cons. These principles guided the choices we made: to remember to put it on every time you go out on the water. Instead, we give you a boat that doesn't sink. You stay dry unless you jump overboard. -* **Null safe code should be easy to write.** Most existing Dart code is +* **Null-safe code should be easy to write.** Most existing Dart code is dynamically correct and does not throw null reference errors. You like your Dart program the way it looks now, and we want you to be able to keep writing code that way. Safety shouldn't require sacrificing usability, paying penance to the type checker, or having to significantly change the way you think. -* **The resulting null safe code should be fully sound.** "Soundness" in the +* **The resulting null-safe code should be fully sound.** "Soundness" in the context of static checking means different things to different people. For us, in the context of null safety, that means that if an expression has a static type that does not permit `null`, then no possible execution of that @@ -95,7 +96,7 @@ pros and cons. These principles guided the choices we made: verify a receiver is non-`null` before calling methods on it. One caveat: We only guarantee soundness in Dart programs that are fully null - safe. Dart supports programs that contain a mixture of newer null safe code + safe. Dart supports programs that contain a mixture of newer null-safe code and older legacy code. In these mixed-version programs, null reference errors may still occur. In a mixed-version program, you get all of the *static* safety benefits in the portions that are null safe, but you don't get full runtime @@ -149,11 +150,11 @@ we've fixed all null reference errors. If we didn't think `null` was useful at all, we could stop here. But `null` is useful, so we still need a way to handle it. Optional parameters are a good -illustrative case. Consider this null safe Dart code: +illustrative case. Consider this null-safe Dart code: ```dart // Using null safety: -makeCoffee(String coffee, [String? dairy]) { +void makeCoffee(String coffee, [String? dairy]) { if (dairy != null) { print('$coffee with $dairy'); } else { @@ -180,11 +181,11 @@ is `null`: ```dart // Hypothetical unsound null safety: -bad(String? maybeString) { +void bad(String? maybeString) { print(maybeString.length); } -main() { +void main() { bad(null); } ``` @@ -211,11 +212,11 @@ flow in and that could fail: ```dart // Hypothetical unsound null safety: -requireStringNotNull(String definitelyString) { +void requireStringNotNull(String definitelyString) { print(definitelyString.length); } -main() { +void main() { String? maybeString = null; // Or not! requireStringNotNull(maybeString); } @@ -227,11 +228,11 @@ type `Object` to a function expecting a `String`, the type checker allows it: ```dart // Without null safety: -requireStringNotObject(String definitelyString) { +void requireStringNotObject(String definitelyString) { print(definitelyString.length); } -main() { +void main() { Object maybeString = 'it is'; requireStringNotObject(maybeString); } @@ -252,11 +253,11 @@ explicit downcast yourself: ```dart // Using null safety: -requireStringNotObject(String definitelyString) { +void requireStringNotObject(String definitelyString) { print(definitelyString.length); } -main() { +void main() { Object maybeString = 'it is'; requireStringNotObject(maybeString as String); } @@ -720,7 +721,7 @@ String checkList(List list) { ``` Dart had no way of knowing if that null-aware `?.` operator is useful or not. -For all it knows, you could pass `null` to the function. But in null safe Dart, +For all it knows, you could pass `null` to the function. But in null-safe Dart, if you have annotated that function with the now non-nullable `List` type, then it knows `list` will never be `null`. That implies the `?.` will never do anything useful and you can and should just use `.`. @@ -834,7 +835,7 @@ can and should write: ```dart // Using null safety: -showGizmo(Thing? thing) { +void showGizmo(Thing? thing) { print(thing?.doohickey.gizmo); } ``` @@ -844,7 +845,7 @@ don't. If you see code like: ```dart // Using null safety: -showGizmo(Thing? thing) { +void showGizmo(Thing? thing) { print(thing?.doohickey?.gizmo); } ``` @@ -967,7 +968,7 @@ class Coffee { String serve() => _temperature + ' coffee'; } -main() { +void main() { var coffee = Coffee(); coffee.heat(); coffee.serve(); @@ -1270,7 +1271,7 @@ class Box { Box(this.object); } -main() { +void main() { Box('a string'); Box(null); } @@ -1329,7 +1330,7 @@ valid value for `T`: ```dart // Using null safety: -main() { +void main() { var box = Box.full(null); print(box.unbox()); } @@ -1462,7 +1463,7 @@ the soundness guarantees if you created a list of a non-nullable type and then accessed an element. To avoid that, we have removed the constructor entirely. It is an error to call -`List()` in null safe code, even with a nullable type. That sounds scary, but +`List()` in null-safe code, even with a nullable type. That sounds scary, but in practice most code creates lists using list literals, `List.filled()`, `List.generate()`, or as a result of transforming some other collection. For the edge case where you want to create an empty list of some type, we added a