Dart/Flutter 个空安全问题
Dart/Flutter problems with null-safety
在不同的情况下,我在 Dart 中多次遇到空语句 (?) 的相同问题。我真的希望有人能帮助我。
刚刚添加了一些代码行和错误:
错误:
The property 'isEmpty' can't be unconditionally accessed because the receiver can be 'null'. Try making the access conditional (using '?.') or adding a null check to the target ('!'). here
这是我的例子之一:
child: MaterialButton(
onPressed: () {
var currentState = this._formKey.currentState;
if (currentState == null) {
return;
}
if (_formKey.currentState.validate()) {
AuthService.instance.signIn(
email: emailTextEditingController.text,
password:
passwordTextEditingController.text);
if (AuthService.instance
.checkIfUserExists() ==
true) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => MainMenu()));
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
VerifyScreen()));
}
}
},
再次收到此错误消息:
The method 'validate' can't be unconditionally invoked because the receiver can be 'null'.Try making the call conditional (using '?.') or adding a null check to the target ('!').
在我用 !避免像这样的空语句:
singUpUser() {
if (formKey.currentState!.validate()) {
setState(() {
isLoading = true;
});
} else {
return null;
};
但是现在我只是避免了代码本身的错误,在启动模拟器并测试它之后,出现了下一个错误:
Null check operator used on a null value
所以这不是正确的解决方案...
如果您需要更多代码,请给我发消息。
谢谢!
汤姆
为空与为空不同。因此,在检查对象是否为空之前,您需要先检查空值。
if (obj != null && !obj.isEmpty) {}
简而言之:如果 Dart 确定 一个变量在编译时可以在[=69时null
=]时间,它不会编译.. 除非你明确检查空值,and/or使用!
运算符将变量提升为不可空(Dart 在某些情况下并不总是能够推断出不可空性,因此我们有责任将它们提升为不可空性)。
如果您好奇(“为什么?”,对于初学者),还有很多要知道的,所以我建议 check the null safety documentation(快速阅读)。
也就是说,您的代码现在发生了变化:
(1) 在访问它之前,我们必须检查 val
是否可以为空。我们可以使用 !
或 .?
来安全地访问它; 注意:空值检查运算符!
是最不安全的空值运算符,它很可能会导致运行时间例外。
validator: (val) {
val==null || val?.isEmpty || val?.length<3
? "Enter Username 3+ characters"
: null
}
(2)我自己无法推断哪个方法/变量可以为null
(3) 这取决于您要做什么,但我猜您正在尝试实施 Firebase 身份验证过程,您的用户 可以并且应该 在验证之前为空。因此,您的函数应该接受 nullable 用户值 (User?
)。在那里,我们进行通常的 null
检查,并添加一个 !
运算符以提升其值,以防 user
不是 null
。如前所述,Dart 并不总是能够推断变量的可空性。
MyUser _userFromFirebaseUser(User? user) {
return user==null ? null : MyUser(userId: user!.uid);
}
请注意,这里使用 null 检查 !
是完全安全的,只是因为您刚刚在同一行中检查了它的可空性(尽管如此,重构时请保持明智的眼光)。
编辑。 (4)
我无法推断出你的异常到底在哪里被触发,但既然你想验证你的表单,那么这是我的一个项目中的代码:
// inside "saveForm()"...
var currentState = this._formKey.currentState;
if (currentState == null)
return; // this just means something went wrong
if (!currentState.validate()) return; // todo if invalid, handle this, maybe show a snackbar and stuff...
请注意变量 currentState
现在如何使用 null 检查运算符 !
提升为不可空的 WITHOUT,这是一个很好的做法(尽可能避免使用 !
,最好使用空感知运算符,例如 ?.
或 ??
,或 ?=
)
在不同的情况下,我在 Dart 中多次遇到空语句 (?) 的相同问题。我真的希望有人能帮助我。
刚刚添加了一些代码行和错误:
错误:
The property 'isEmpty' can't be unconditionally accessed because the receiver can be 'null'. Try making the access conditional (using '?.') or adding a null check to the target ('!'). here
这是我的例子之一:
child: MaterialButton(
onPressed: () {
var currentState = this._formKey.currentState;
if (currentState == null) {
return;
}
if (_formKey.currentState.validate()) {
AuthService.instance.signIn(
email: emailTextEditingController.text,
password:
passwordTextEditingController.text);
if (AuthService.instance
.checkIfUserExists() ==
true) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => MainMenu()));
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
VerifyScreen()));
}
}
},
再次收到此错误消息:
The method 'validate' can't be unconditionally invoked because the receiver can be 'null'.Try making the call conditional (using '?.') or adding a null check to the target ('!').
在我用 !避免像这样的空语句:
singUpUser() {
if (formKey.currentState!.validate()) {
setState(() {
isLoading = true;
});
} else {
return null;
};
但是现在我只是避免了代码本身的错误,在启动模拟器并测试它之后,出现了下一个错误:
Null check operator used on a null value
所以这不是正确的解决方案...
如果您需要更多代码,请给我发消息。
谢谢!
汤姆
为空与为空不同。因此,在检查对象是否为空之前,您需要先检查空值。
if (obj != null && !obj.isEmpty) {}
简而言之:如果 Dart 确定 一个变量在编译时可以在[=69时null
=]时间,它不会编译.. 除非你明确检查空值,and/or使用!
运算符将变量提升为不可空(Dart 在某些情况下并不总是能够推断出不可空性,因此我们有责任将它们提升为不可空性)。
如果您好奇(“为什么?”,对于初学者),还有很多要知道的,所以我建议 check the null safety documentation(快速阅读)。
也就是说,您的代码现在发生了变化:
(1) 在访问它之前,我们必须检查 val
是否可以为空。我们可以使用 !
或 .?
来安全地访问它; 注意:空值检查运算符!
是最不安全的空值运算符,它很可能会导致运行时间例外。
validator: (val) {
val==null || val?.isEmpty || val?.length<3
? "Enter Username 3+ characters"
: null
}
(2)我自己无法推断哪个方法/变量可以为null
(3) 这取决于您要做什么,但我猜您正在尝试实施 Firebase 身份验证过程,您的用户 可以并且应该 在验证之前为空。因此,您的函数应该接受 nullable 用户值 (User?
)。在那里,我们进行通常的 null
检查,并添加一个 !
运算符以提升其值,以防 user
不是 null
。如前所述,Dart 并不总是能够推断变量的可空性。
MyUser _userFromFirebaseUser(User? user) {
return user==null ? null : MyUser(userId: user!.uid);
}
请注意,这里使用 null 检查 !
是完全安全的,只是因为您刚刚在同一行中检查了它的可空性(尽管如此,重构时请保持明智的眼光)。
编辑。 (4) 我无法推断出你的异常到底在哪里被触发,但既然你想验证你的表单,那么这是我的一个项目中的代码:
// inside "saveForm()"...
var currentState = this._formKey.currentState;
if (currentState == null)
return; // this just means something went wrong
if (!currentState.validate()) return; // todo if invalid, handle this, maybe show a snackbar and stuff...
请注意变量 currentState
现在如何使用 null 检查运算符 !
提升为不可空的 WITHOUT,这是一个很好的做法(尽可能避免使用 !
,最好使用空感知运算符,例如 ?.
或 ??
,或 ?=
)