Flutter/dart模型中空值处理

djmepvbi  于 2023-09-28  发布在  Flutter
关注(0)|答案(3)|浏览(158)

我有一个模型,它看起来像这样

class UserModel {
  final String? username;
  final int? age;
  final String? phoneNumber;

  UserModel(
      {required this.age, required this.phoneNumber, required this.username});

  @override
  String toString() {
    return 'Username => $username\nAge => $age\nPhone number => $phoneNumber';
  }
}

我现在困惑的是什么更好地使用?还是没有?例如final String? usernamefinal String username
如果我从服务器username获取的数据为空,我该如何处理?我想保持UI代码尽可能干净,所以我不想把if(user.username == null)在UI我想保持它在模型或控制器如何?

gtlvzcf8

gtlvzcf81#

在Dart中,在类型(例如String?)之后使用?表示该变量可以为空,这意味着它可以保存该类型的非空值或null。另一方面,如果声明一个没有?的变量(例如String),这意味着该变量必须始终包含该类型的非空值。
UserModel类中,您已经将字段定义为可空:

final String? username;
final int? age;
final String? phoneNumber;

这意味着这些字段可以分配null值。应使用可空类型还是不可空类型取决于应用程序的要求以及希望如何处理空值。以下是一些注意事项:

  • 在以下情况下使用可空类型(String?int?等):
  • 您期望接收到的数据可能有缺失值或空值,并且希望在模型中表示这些数据。
  • 例如,您希望区分空值和空字符串。
  • 您希望在访问这些字段时避免运行时空引用异常。
  • 在以下情况下使用不可空类型(Stringint等):
  • 您期望数据应该始终具有有效的非空值,空值将指示编程错误或数据完整性问题。
  • 您希望在创建模型示例时强制这些字段始终使用有效值进行初始化。

关于你的第二个问题,如何在不扰乱UI代码的情况下处理模型或控制器中的空值,你可以通过在构造UserModel对象时提供默认值或转换数据来实现这一点。下面是一个如何在模型构造函数中处理null值的示例:

class UserModel {
  final String username;
  final int age;
  final String phoneNumber;

  UserModel({
    String? username,
    int? age,
    String? phoneNumber,
  })  : username = username ?? 'Default Username',
        age = age ?? 0,
        phoneNumber = phoneNumber ?? 'N/A';

  @override
  String toString() {
    return 'Username => $username\nAge => $age\nPhone number => $phoneNumber';
  }
}

在这个修改后的UserModel中,如果任何提供的值(用户名,年龄或电话号码)是null,它将默认为指定的值(例如,用户名的“默认用户名”),而不是允许空值。通过这种方式,可以确保UserModel始终包含非空值,这可以使UI代码中的操作更容易。

mu0hgdu0

mu0hgdu02#

我建议不要在类属性中包含**?操作符。现在,它不是强制性的,但是,从减少null异常的Angular 来看,你的代码必须是null安全的,或者,你应该根据需要使用?**。
根据我的经验,有这样一个类,是一个很好的结构。

class UserModel {
  final String username;
  final int age;
  final String phoneNumber;

  UserModel({
    required this.username,
    required this.age,
    required this.phoneNumber,
  });
}

您可能会问,如果我的phoneNumber不是required,那么创建一个UserModel,我将如何管理它。在这种情况下,让我们**remove**this.phoneNumberconstructor中的requried关键字并分配default valuedefault value将只分配,当且仅当,您没有提供任何phoneNumber作为参数,同时创建UserModel对象。

class UserModel {
  final String username;
  final int age;
  final String phoneNumber;

  UserModel({
    required this.username,
    required this.age,
    this.phoneNumber = "",
  });
}

另一种重写同样内容的方法是

class UserModel {
  final String username;
  final int age;
  final String phoneNumber;

  UserModel({
    required this.username,
    required this.age,
    required String? phoneNumber,
  }) : phoneNumber = phoneNumber ?? "";
}

对于服务器数据处理,我建议在保持上述结构的同时使用工厂构造函数。

class UserModel {
  final String username;
  final int age;
  final String phoneNumber;

  UserModel({
    required this.username,
    required this.age,
    required this.phoneNumber,
  });

  factory UserModel.fromServer(Map<String, dynamic> map) {
    return UserModel(
      username: map["username"], // assuming username can't be null
      age: map["age"], // assuming age can't be null
      phoneNumber: map["phoneNumber"] ?? "",  // assuming phoneNumber can be null
    );
  }
}

总结一下答案,你应该在大多数时候避免使用**nullable变量。这并不意味着你不应该使用nullable数据类型。如果您想通过检查值是否为null来检查是否提供了phoneNumber**,该怎么办?我的意思是谁检查数据提供或不通过检查它是否为空或不(actualy我做)。

to94eoyn

to94eoyn3#

我在我的DTO对象中使用可空字段,因为我希望它们尽可能“接近金属”用于输入/输出。但是,在我的数据域对象(也称为“业务对象”)中,如果值是可选的,我更喜欢fpdartOption Package 器,以保证在故意缺少值时有一个哨兵。

相关问题