【问题标题】:Null-safety for fromJson like methodsfromJson 类方法的空安全性
【发布时间】:2021-07-12 17:40:29
【问题描述】:

我想在Flutter 2.0.5 中定义一个简单的类模型UserResponse 并构建一个附加到该类的fromJson 方法,以便在从后端接收到json格式的数据后轻松创建一个实例。

class UserResponse {
  String name;

  UserResponse ({
    required this.name,
  });

  UserResponse.fromJson(Map<String, dynamic> json) {
    name= json['name'].toString();
  }
}

然而,dart 编译器在这里抛出一个错误: dart(not_initialized_non_nullable_instance_field)

此外: 必须初始化不可为空的实例字段“名称”。 尝试添加初始化表达式,或在此构造函数中添加字段初始化,或将其标记为“延迟”。

如果我知道如果我拥有所有必需的数据,我只会调用fromJson 方法,我应该如何在这个方法中创建新的实例?我不想将类中的name 字段更改为late

【问题讨论】:

    标签: json flutter dart-null-safety


    【解决方案1】:

    使用factory 构造函数。

    class UserResponse {
      final String name;
    
      UserResponse({
        required this.name,
      });
    
      factory UserResponse.fromJson(Map<String, dynamic> json) {
        return UserResponse(name: json['name'].toString());
      }
    }
    

    【讨论】:

      【解决方案2】:

      根据这个非常相似的question主要有办法:

      1. 为方法使用初始化列表

      2. 使用工厂方法

      因此,

      UserResponse.fromJson(Map<String, dynamic> json) :
              name= json['name'] as String;
      

      factory UserResponse.fromJson(Map<String, dynamic> json) {
              return UserResponse(
                  name: json['name'] as String,
              );
          }
      

      【讨论】:

        【解决方案3】:

        为了零安全。您需要以正确的方式检查 null。并且前端需要handle server不返回这个key,我们需要mock数据,保证app不会崩溃。

        class UserResponse {
          UserResponse({
            this.name,
          });
        
          final String? name;
        
          factory UserResponse.fromRawJson(String str) =>
              UserResponse.fromJson(json.decode(str));
        
          String toRawJson() => json.encode(toJson());
        
          factory UserResponse.fromJson(Map<String, dynamic> json) => UserResponse(
                name: json["name"] == null ? null : json["name"].toString(),
              );
        
          Map<String, dynamic> toJson() => {
                "name": name == null ? null : name,
              };
        }
        

        【讨论】:

        • toJsonfromJson 方法有一些冗余,模型中的 name 变量不是空安全的。这不是解决问题的回应。只需使用我接受的答案,因为它 100% 满足了问题。
        • 如果从服务器返回的 JSON 没有密钥 name 您的应用程序将崩溃(期望字符串但得到 Null .....)。我的代码解决了这个问题。
        • 首先,这不是要求的。其次,不,它没有。 name: json["name"] == null ? null : json["name"].toString(), 出于多种原因无用。您不需要对字符串使用 toString() 方法。当您在上面声明final String? name; 时,您不需要对可空类型进行空检查,无论如何,如果它是null,您只是分配null,所以完全多余。
        • 哦。我忘记了final String? name; 默认设置名称null。谢谢!不错。
        猜你喜欢
        • 2017-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-11
        • 2014-10-21
        • 2021-01-18
        • 2015-12-07
        • 2014-03-07
        相关资源
        最近更新 更多