在 Flutter 中声明一个没有初始化器的变量,具有空安全性
Declaring a variable with no initialiser in Flutter, with null safety
我正在尝试使用 Flutter 在我的应用程序中实施 Firebase 身份验证,并且我的编码最初工作正常,但自从我将项目迁移到 null safety 后,身份验证不再有效。我想我有 'isolated' 在那里。
例如,如果我们使用我的密码重置 TextField,就代码而言,这就是 TextField 的样子:
TextField _buildEmailTextField() {
return TextField(
controller: _emailController,
focusNode: _emailFocusNode,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'email@address.com',
errorText: model.emailErrorText,
enabled: model.isLoading == false,
),
autocorrect: false,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
onChanged: model.updateEmail,
onEditingComplete: _submit,
);
}
当然,为了处理TextField的变化,你可以看到我添加了一个updateEmail函数onChanged: model.updateEmail
。该函数本身如下所示:
void updateEmail(String email) => updateWith(email: email);
updateWith 函数如下所示:
void updateWith({
String email = '',
bool isLoading = false,
bool submitted = false,
}) {
this.email = email;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
在空安全之前,我不需要用值初始化 updateWith
中的变量,所以它看起来像这样:
void updateWith({
String email,
bool isLoading,
bool submitted,
}) {
this.email = email;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
来自 Firebase 的错误是:
[firebase_auth/missing-email] An email address must be provided
我认为这是由于我现在必须在 updateWith
中初始化 email
变量,并且我使用的是空字符串。因此,即使我在 TextField 中输入电子邮件,当我提交时,它也会提交空字符串,因此 Firebase 会告诉我我还没有提交电子邮件。我尝试过使用电子邮件作为可空值,如下所示:
void updateWith({
String? email,
bool isLoading = false,
bool submitted = false,
}) {
this.email = email!;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
但是这给了我错误:
Null check operator used on a null value
既然我已经迁移到 null safety,我该如何使我的 updateWith 函数工作?正如我所说,它在空安全之前运行良好,所以我对逻辑很有信心。只是现在必须用函数内的变量初始化 email
意味着初始变量被提交给 firebase,而不是输入的电子邮件地址。有没有办法让这个工作,或者我可以重写我的 updateEmail
和 updateWith
函数,这样它们就不必用值初始化?
如果您需要我提供任何其他信息,我很乐意提供。谢谢指教!
改变void updateEmail(String email) => updateWith(email: email);
到void updateEmail(String? email) => updateWith(email: email);
该方法对于 Dart/Flutter 开发人员来说非常不直观,除非您使用通用模式来实现。像这样的方法中那些可选参数的要点通常是只传递其中的几个,其余的保持不变。因此,例如,您可以仅调用 updateWith(email: 'test@example.com')
和 ,email
将更新,但 isLoading
和 submitted
将保持不变。你只能在参数可以为空的情况下实现这一点,所以你有一个 marker/value 可以检查“根本没有设置”。
例如:
void updateWith({
String? email,
bool? isLoading,
bool? submitted,
}) {
this.email = email ?? this.email;
this.isLoading = isLoading ?? this.isLoading;
this.submitted = submitted ?? this.submitted;
notifyListeners();
}
如果 email
是必需的参数,而其他两个无论如何都会设置为默认值,那么您根本不需要命名参数。只需将其设为具有正常位置参数的正常方法即可。
空安全并不意味着从不使用 null
。如果某些东西在 null-safety 之前工作,它仍然可以通过使用可空类型在之后工作。
updateWith
和 copyWith
等函数通常旨在 仅使用 提供的参数,其余的不用理会。因此,这通常意味着使参数可为空:
void updateWith({
String? email,
bool? isLoading,
bool? submitted,
}) {
this.email = email ?? this.email;
this.isLoading = isLoading ?? this.isLoading;
this.submitted = submitted ?? this.submitted;
notifyListeners();
}
(请注意,如果调用者未提供 updateWith
的原始实现并没有这样做,并且无条件地使用 null
破坏字段。如果这实际上是您想要的行为,那么函数名称用词不当。)
我正在尝试使用 Flutter 在我的应用程序中实施 Firebase 身份验证,并且我的编码最初工作正常,但自从我将项目迁移到 null safety 后,身份验证不再有效。我想我有 'isolated' 在那里。
例如,如果我们使用我的密码重置 TextField,就代码而言,这就是 TextField 的样子:
TextField _buildEmailTextField() {
return TextField(
controller: _emailController,
focusNode: _emailFocusNode,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'email@address.com',
errorText: model.emailErrorText,
enabled: model.isLoading == false,
),
autocorrect: false,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
onChanged: model.updateEmail,
onEditingComplete: _submit,
);
}
当然,为了处理TextField的变化,你可以看到我添加了一个updateEmail函数onChanged: model.updateEmail
。该函数本身如下所示:
void updateEmail(String email) => updateWith(email: email);
updateWith 函数如下所示:
void updateWith({
String email = '',
bool isLoading = false,
bool submitted = false,
}) {
this.email = email;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
在空安全之前,我不需要用值初始化 updateWith
中的变量,所以它看起来像这样:
void updateWith({
String email,
bool isLoading,
bool submitted,
}) {
this.email = email;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
来自 Firebase 的错误是:
[firebase_auth/missing-email] An email address must be provided
我认为这是由于我现在必须在 updateWith
中初始化 email
变量,并且我使用的是空字符串。因此,即使我在 TextField 中输入电子邮件,当我提交时,它也会提交空字符串,因此 Firebase 会告诉我我还没有提交电子邮件。我尝试过使用电子邮件作为可空值,如下所示:
void updateWith({
String? email,
bool isLoading = false,
bool submitted = false,
}) {
this.email = email!;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
但是这给了我错误:
Null check operator used on a null value
既然我已经迁移到 null safety,我该如何使我的 updateWith 函数工作?正如我所说,它在空安全之前运行良好,所以我对逻辑很有信心。只是现在必须用函数内的变量初始化 email
意味着初始变量被提交给 firebase,而不是输入的电子邮件地址。有没有办法让这个工作,或者我可以重写我的 updateEmail
和 updateWith
函数,这样它们就不必用值初始化?
如果您需要我提供任何其他信息,我很乐意提供。谢谢指教!
改变void updateEmail(String email) => updateWith(email: email);
到void updateEmail(String? email) => updateWith(email: email);
该方法对于 Dart/Flutter 开发人员来说非常不直观,除非您使用通用模式来实现。像这样的方法中那些可选参数的要点通常是只传递其中的几个,其余的保持不变。因此,例如,您可以仅调用 updateWith(email: 'test@example.com')
和 ,email
将更新,但 isLoading
和 submitted
将保持不变。你只能在参数可以为空的情况下实现这一点,所以你有一个 marker/value 可以检查“根本没有设置”。
例如:
void updateWith({
String? email,
bool? isLoading,
bool? submitted,
}) {
this.email = email ?? this.email;
this.isLoading = isLoading ?? this.isLoading;
this.submitted = submitted ?? this.submitted;
notifyListeners();
}
如果 email
是必需的参数,而其他两个无论如何都会设置为默认值,那么您根本不需要命名参数。只需将其设为具有正常位置参数的正常方法即可。
空安全并不意味着从不使用 null
。如果某些东西在 null-safety 之前工作,它仍然可以通过使用可空类型在之后工作。
updateWith
和 copyWith
等函数通常旨在 仅使用 提供的参数,其余的不用理会。因此,这通常意味着使参数可为空:
void updateWith({
String? email,
bool? isLoading,
bool? submitted,
}) {
this.email = email ?? this.email;
this.isLoading = isLoading ?? this.isLoading;
this.submitted = submitted ?? this.submitted;
notifyListeners();
}
(请注意,如果调用者未提供 updateWith
的原始实现并没有这样做,并且无条件地使用 null
破坏字段。如果这实际上是您想要的行为,那么函数名称用词不当。)