【问题标题】:Dart check nullable TypeDart 检查可空类型
【发布时间】:2022-08-02 11:38:14
【问题描述】:

我想找到一种方法来检查类型是否可以使用 switch 语句为空,但这样做会出错。没有人知道如何检查对象的类型是否处于可空状态?

void dataFactory(Type type, data){
    switch(type){
      case A:
        return A.fromJson(data);
        case A?: // Getting error Conditions must have a static type of \'bool\'
          return A.fromJson(data);
      case B:
        return B.fromJson(data);
    }
  }

    标签: flutter dart dart-null-safety


    【解决方案1】:

    您可以创建一个函数Type getType<T>() => T;,但由于getType<A?>() 不会被视为一个常量值,您将无法将它与switch 语句一起使用:

    Type getType<T>() => T;
    
    dynamic dataFactory(Type type, Map<String, dynamic> data) {
      if (type == A || type == getType<A?>()) {
         return A.fromJson(data);
      } else if (type == B) {
         return B.fromJson(data);
      }
      ...
    }
    

    另一种方法是使用Map 的回调:

    Type getType<T>() => T;
    
    final _factoryMap = <Type, dynamic Function(Map<String, dynamic>)>{
      A: A.fromJson,
      getType<A?>(): A.fromJson,
      B: B.fromJson,
    };
    
    dynamic dataFactory(Type type, Map<String, dynamic> data) =>
        _factoryMap[type]?.call(data);
    

    【讨论】:

    • 第二种方法很好,但在我的情况下不起作用。我需要转换为动态"{A: A.fromJson as dynamic}",但它在运行时出错。
    • @user102232 转换 Functions 几乎总是错误的。如果A.fromJson 被声明为static A fromJson(dynamic data) { ... }B.fromJson 也是如此),则第二种方法应该有效。如果他们采用不同类型的参数,那么您要么需要更改 _factoryMap 的类型,要么需要将 A.fromJson 包装在匿名函数中有正确的签名。我不知道A.fromJsonB.fromJson 是什么样子,所以无法为您提供更具体的帮助。
    • json 函数看起来像这样factory A.fromJson(Map&lt;String, dynamic&gt; json)
    • @user102232 好的,你的 dataFactory 函数没有为 data 提供类型,所以 Dart(和我)假设它是 dynamic。如果A.fromJsonB.fromJson 都期望Map&lt;String, dynamic&gt; 参数,那么第二种方法只需要使用期望Map&lt;String, dynamic&gt; 参数的回调。我已经更新了我的答案。
    【解决方案2】:

    你的问题是:

    我想找到一种方法来检查类型是否可以使用 switch 语句为空。没有人知道如何检查对象的类型是否处于可空状态?

    即使我没有使用switch 语句,我想您也可以使用this answer 并通过创建新的列表实例来验证泛型类型是否可以为空。

    笔记:我假设我们可以用泛型类型T 替换Type 类型参数实例。由于 Flutter 禁用反射,这是我们可以用来验证给定类型 T 性质(是否为空)的唯一方法。

    bool isNullable<T>() => <T?>[] is List<T>;
    

    您也可以调整此功能以满足您的需求:

    bool checkTypes<X, Y>() => <X>[] is List<Y> && <Y>[] is List<X>;
    

    并将其用作:

    T dataFactory<T>(dynamic data) {
      if(checkTypes<T, A>()) {
        // Non-nullable [A]
      } else if(checkTypes<T, A?>()) {
        // Nullable [A]
      }
    
      /// Repeat with [B], [C], etc.
    }
    

    你也可以测试它:

    void main() {
      print(checkTypes<A, A>()); // true
      print(checkTypes<B?, B>()); // false
      print(checkTypes<B?, B?>()); // true
    }
    

    【讨论】:

    • 我相信这个解决方案也会,但它看起来很像一个黑客。而且@jamesdlin 使用起来更好更简单。
    猜你喜欢
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多