flutter - (Flutter) 升级到 NullSafety
问题描述
嗨,我正在尝试将旧代码升级为 null 安全性,但由于我刚刚开始学习 null 安全性,所以我遇到了错误,我不知道为什么,如果你能提供帮助,我会很高兴。
我已经尝试了一些东西,但我将其保留为原始形式,以免让您进一步混淆。源代码:https ://github.com/MarcusNg/flutter_instagram
auth_event
part of 'auth_bloc.dart';
abstract class AuthEvent extends Equatable {
const AuthEvent();
@override
bool get stringify => true;
@override
List<Object> get props => [];
}
class AuthUserChanged extends AuthEvent {
final auth.User user;
const AuthUserChanged({required this.user});
@override
List<Object> get props => [user];
}
class AuthLogoutRequested extends AuthEvent {}
auth_state
part of 'auth_bloc.dart';
enum AuthStatus { unknown, authenticated, unauthenticated }
class AuthState extends Equatable {
final auth.User user;
final AuthStatus status;
const AuthState({
this.user,
this.status = AuthStatus.unknown,
});
factory AuthState.unknown() => const AuthState();
factory AuthState.authenticated({required auth.User user}) {
return AuthState(user: user, status: AuthStatus.authenticated);
}
factory AuthState.unauthenticated() =>
const AuthState(status: AuthStatus.unauthenticated);
@override
bool get stringify => true;
@override
List<Object> get props => [user, status];
}
- 参数 'user' 的值不能为 'null',因为它的类型,但隐含的默认值是 'null'。尝试添加显式的非“null”默认值或“required”修饰符。(这个用户)
auth_bloc
part 'auth_event.dart';
part 'auth_state.dart';
class AuthBloc extends Bloc<AuthEvent, AuthState> {
final AuthRepository _authRepository;
StreamSubscription<auth.User> _userSubscription;
AuthBloc({
required AuthRepository authRepository,
}) : _authRepository = authRepository,
super(AuthState.unknown()) {
_userSubscription =
_authRepository.user.listen((user) => add(AuthUserChanged(user: user)));
}
@override
Future<void> close() {
_userSubscription?.cancel();
return super.close();
}
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
if (event is AuthUserChanged) {
yield* _mapAuthUserChangedToState(event);
} else if (event is AuthLogoutRequested) {
await _authRepository.logOut();
}
}
Stream<AuthState> _mapAuthUserChangedToState(AuthUserChanged event) async* {
yield event.user != null
? AuthState.authenticated(user: event.user)
: AuthState.unauthenticated();
}
}
必须初始化不可为空的实例字段“_userSubscription”。尝试添加初始化表达式,或在此构造函数中添加字段初始化程序,或将其标记为“迟到”。
“StreamSubscription<User?>”类型的值不能分配给“StreamSubscription”类型的变量。尝试更改变量的类型,或将右侧类型转换为“StreamSubscription”。
参数类型“用户?” 不能分配给参数类型“用户”。(_authRepository.user.listen((user) => add(AuthUserChanged(user: user)));)
接收者不能为空,因此可识别空值的运算符 '?.' 是不必要的。尝试替换运算符'?.' 和 '。'。(_userSubscription?.cancel();)
操作数不能为空,因此条件始终为真。删除条件。(event.user != null)
解决方案
参数 'user' 的值不能为 'null',因为它的类型,但隐含的默认值是 'null'。尝试添加显式的非“null”默认值或“required”修饰符。(这个用户)
发生此错误是因为您已将user
变量设置为不可为空并且final
. 如果您不熟悉 nullsafety,要使变量可以为空,只需?
在类型末尾添加 a。有两种不同的方法可以解决这个问题:
- 如果您知道这
user
永远不会为空,那么只需执行以下操作:
const AuthState({
required this.user,
this.status = AuthStatus.unknown,
});
required
告诉编译器“嘿,这个变量永远不能设置为空”。
- 如果
user
可以为空,则执行final auth.User? user;
. 告诉编译器“嘿,这个?
变量可能是 null`。
但是,在您的情况下,由于此代码,您必须使用选项 2:
factory AuthState.unauthenticated() =>
const AuthState(status: AuthStatus.unauthenticated);
由于你没有传入user
构造函数,你必须告诉 Dart 变量可以为空。
必须初始化不可为空的实例字段“_userSubscription”。尝试添加初始化表达式,或在此构造函数中添加字段初始化程序,或将其标记为“迟到”。
在此处添加late
标识符:late StreamSubscription<auth.User> _userSubscription;
. 这告诉 Dart 是的,变量永远不会为空,我只是在定义它时没有设置它。在其他地方使用之前,我会将其设置为非空值。
“StreamSubscription<User?>”类型的值不能分配给“StreamSubscription”类型的变量。尝试更改变量的类型,或将右侧类型转换为“StreamSubscription”。
由于 nullsafety,Dart 现在有更严格的类型检查,所以对于这一行,我认为你需要更改这一行:StreamSubscription<auth.User> _userSubscription;
into StreamSubscription<auth.User?> _userSubscription;
(不要忘记late
像我之前提到的那样添加)。
参数类型“用户?” 不能分配给参数类型“用户”。(_authRepository.user.listen((user) => add(AuthUserChanged(user: user)));)
在AuthUserChanged
,你做了auth.User user
required
。在该代码行中,您将一个可为空的变量分配给一个不可为空的变量。因此,您必须将类更改为如下所示:
class AuthUserChanged extends AuthEvent {
final auth.User? user;
const AuthUserChanged({this.user});
@override
List<Object> get props => [user];
}
接收者不能为空,因此可识别空值的运算符 '?.' 是不必要的。尝试替换运算符'?.' 和 '。'。(_userSubscription?.cancel();)
这只是一个警告,您所要做的就是_userSubscription?.cancel();
将_userSubscription.cancel();
. 警告只是让您知道它_userSubscription
永远不会为空,因此您无需使用?
运算符检查它是否为空。
操作数不能为空,因此条件始终为真。删除条件。(event.user != null)
与之前的条件相同。只是一个警告,您所要做的就是删除该行代码,因为它是不必要的。
希望这对你有帮助!我建议查看 Dart 的 nullsafety 文档,以更好地了解所有新运算符和关键字的工作原理。
推荐阅读
- html - 如何在 Ionic4 中将离子载玻片与离子卡结合起来?
- tornadofx - 如何在 Kotlin/Native 中使用 TornadoFx
- sql - 在一行上获取多行的一些列
- asp.net-mvc - Asp.Net MVC Core ViewModel与模型结合问题
- azure - Azure DevOps 中的 Docker 错误,但不在本地?
- node.js - 无法解析 api 服务器容器的 /usr/src/app 中的 sequelize 包?
- python - 如何根据Django中的属性值将模型实例复制到另一个模型
- swagger-2.0 - 从 OpenAPI 3 中的模式部分检索多个对象
- python - 定义地图
> 返回类型在每次运行时给出随机值 - c# - 如何在 LiveCharts 中使用 ObservableValue 的 AddRange?