Flutter2 empty security, avoid App empty value crash problem

what is null safe

Starting from Flutter2, Flutter enables null safety by default in the configuration, and merges it into the type system through null checks, which can catch these errors during the development process and prevent crashes caused by the production environment.

At present, Kotlin, Swift, Rust, etc. have their own support for null safety. Dart has supported null safety since version 2.12. Through null safety, developers can effectively avoid null error crashes. Null safety can be said to be an important part of the Dart language. Complementary, which further enhances the type system by distinguishing between types and non-nullable types.

Null Safety Benefits

  • Can turn what would have been a runtime null value into an edit-time parse error.
  • Enhance program robustness and effectively avoid crashes caused by Null.
  • Follow the development trend of Dart and Flutter, leaving no pitfalls for the subsequent iterations of the program.

Essential Knowledge for Air Safety

  • air safety principles
  • Changes to the Dart type system before and after the introduction of null safety
  • Use of nullable (?) types
  • Use of lazy initialization (late)
  • Use of the null assertion operator (!)

air safety principles

Dart's null-safe support is based on three core principles:

  • Non-nullable by default: Unless a variable is declared as nullable, it must be of a non-nullable type
  • Gradual migration: You can freely choose when to migrate and how much code to migrate.
  • Completely reliable: Dart's null safety is very reliable, which means that many optimizations are included during compilation
    • If the type system deduces that a variable is not null, then it will never be null, and when you fully migrate your entire project and other dependencies to null safety, you get all the benefits of soundness—fewer bugs, smaller binaries and faster execution.

Changes to the Dart type system before and after the introduction of null safety

Before the introduction of null safety, Dart's type system is like this:
insert image description here
This means that before, all types can be Null, that is, the Null type is regarded as a subclass of all types. After the introduction of null safety:
insert image description here
it can be seen that the biggest change is to separate the Null type, which means that Null is no longer a subtype of other types, so when a Null value is passed to a variable of a non-Null type, a type conversion will be reported mistake. Tip: In Flutter or Dart projects that use empty safety, you will often see a large number of applications of ?., !, late, so what are they and how to use them? Please see the analysis below:

Use of nullable (?) types

We can pass the ? Follow the type to indicate that the variable or parameter following it accepts Null:

class CommonModel {
    
    
	String? firstName; //可空的成员变量
	int getNameLen(String? last/*可空的参数*/){
    
    
		int firstLen = firstName?.length ?? 0;
		int lastLen = lastName?.length ?? 0;
		return firstLen + lastLen;
	}
}

Nullable variables or parameters need to be accessed through Dart's space avoidance operator?., otherwise a compilation error will be thrown.

When the program enables null safety, the member variables of the class are non-nullable by default, so for a non-null member variable, you need to specify its initialization method:

class CommonModel {
    
    
	List names=[];//定义时初始化
	final List colors;//在构造方法中初始化
	late List urls;//延时初始化
	CommonModel(this.colors);
{
    
    

Use of lazy initialization (late)

For those who cannot be initialized at definition time and want to avoid using ?., then lazy initialization can help you. The variable modified by late allows developers to choose the timing of initialization, and there is no need to use ?. when using this variable.

late List urls;//延时初始化
setUrls(List urls){
    
    
	this.urls=urls;
}
int getUrlLen() {
    
    
	return urls.length;
}

Although delayed initialization can bring some convenience to our coding, if it is used improperly, it will cause the problem of empty exception, so when using it, the order of assignment and access must be guaranteed, and it must not be reversed.

Delayed initialization (late) usage paradigm:
Some variables initialized in the initState method of State in Flutter are more suitable for delayed initialization using late, because the initState method is executed first in the Widget life cycle, so it is initialized After the variable is modified by late, it can not only ensure the convenience of use, but also prevent empty exceptions.

Use of the null assertion operator (!)

When we exclude the possibility of variables or parameters being nullable, we can use ! to tell the compiler that the nullable variable or parameter is not nullable, which is helpful for us to pass parameters or pass nullable parameters to a non-nullable input parameter is especially useful when:

Widget get _listView{
    
    
	return ListView(
		children: <Widget>[
		_banner,
		Padding(
			padding: EdgeInsets.formLTRB(7, 4, 7, 4),
			child: LocalNav(localNavList: localNavList),
		),
		if (gridNavModel != null)
			Padding(
				padding: EdgeInset.formLTRB(7, 0, 7, 4),
				child: GriNav(gridNavModel: gridNavModel!)),
			Padding(
				padding: EdgeInsets.formLTRB(7, 0, 7, 4),
				child: SubNav(subNavList: subNavList)),
			if (selesBoxModel != null) 
				Padding(
					padding: EdgeInsets.formLTRB(7, 0, 7, 4),
					child: SalesBox(selesBox: salesBoxModel!)),
		],
	);
}

Guess you like

Origin blog.csdn.net/qq_45455361/article/details/122665183