Flutter中实现空实例的常量工厂的最佳方法是什么?(关于freezed的)

3
我正在尝试找出最佳的方法来实现一个常数工厂,以生成定义模型的“空”实例,并保持其原始构造函数严格(没有默认参数就必须传入所有参数)。我找到的最接近的解决方案是使用具有相同参数集的联合类型和密封类。您可以参考Union types and Sealed classes
const factory Costs({
  required bool valid,
  required String names,
  required String prices,
  required String subtotal,
  required String deposit,
  required String deliveryCosts,
  required String total,
  String? errCode,
}) = LoadedCosts;

const factory Costs.empty({
  @Default(false) bool valid,
  @Default('') String names,
  @Default('') String prices,
  @Default('') String subtotal,
  @Default('') String deposit,
  @Default('') String deliveryCosts,
  @Default('') String total,
  String? errCode,
}) = EmptyCosts;

因此,这将使我的主工厂严格,同时允许通过第二个工厂获取空实例。需要注意的重要事项是,我也不必在业务逻辑代码中匹配密封类(两个类中的所有参数都相同,因此我可以直接访问字段)。
有两个要点需要注意:
- 这仍然不够简洁。我必须重新定义所有参数并添加 @Default 装饰器。 - 您可以使用空工厂,但仍然可以传递自定义值,这是理想情况下我想避免的。我希望有一个不接受任何参数的空构造函数。
理想情况下,我希望它看起来像这样:
  const Costs.empty()
  : valid = false,
    names = '',
    prices = '',
    subtotal = '',
    deposit = '',
    deliveryCosts = '',
    total = '',
    errCode = null;

如果您没有使用 freezed,这实际上是有效的。然而,使用 freezed,我需要重定向构造函数,这将带来所有问题。

有什么想法吗?

1个回答

2

您实际上可以这样做。

@freezed
class Costs with _$Costs {
  const factory Costs({
    required bool valid,
    required String names,
    required String prices,
    required String subtotal,
    required String deposit,
    required String deliveryCosts,
    required String total,
    String? errCode,
  }) = LoadedCosts;

  factory Costs.empty() => const LoadedCosts(
        deliveryCosts: '',
        deposit: '',
        names: '',
        prices: '',
        subtotal: '',
        total: '',
        valid: false,
      );
}

或者,如果您想将实例作为构造函数中的默认值传递,您可以使用static const变量。由于它是常量和不可变的,我们无法更改此静态实例的状态。而且,如果我们想在不可变的冻结对象中更改状态,我们会使用.copyWith(),这显然会提供新的实例而不更改现有实例状态。因此我认为这可以帮助。

@freezed
class Costs with _$Costs {
  const factory Costs({
    required bool valid,
    required String names,
    required String prices,
    required String subtotal,
    required String deposit,
    required String deliveryCosts,
    required String total,
    String? errCode,
  }) = LoadedCosts;

  static const emptyCosts = LoadedCosts(
    deliveryCosts: '',
    deposit: '',
    names: '',
    prices: '',
    subtotal: '',
    total: '',
    valid: false,
  );
}

希望这可以帮到您!愉快编码 :)

谢谢你的回答。目前来说,我会接受它,因为没有其他答案。虽然我已经有一段时间没做这个了,但我想我试过这种方法。总体上它运行得很好,但在我的问题中,我强调了需要常量工厂的必要性。原因是:还有其他类(非冻结)是不可变的,并且它们正在尝试在构造函数中设置默认值。所以,这种方式不能使工厂成为常量->我无法将其作为常量放入另一个构造函数中->该类会抱怨它的构造函数需要是常量,因为它是不可变的等等。 - Roman Shirokov
目前,我非常怀疑能否实现我想要的。分析器非常明确地表示:“只有重定向工厂构造函数可以声明为'const'。”因此,它按照我在最初的问题中提出的方式工作,但我猜它永远不会像你的那样工作。 - Roman Shirokov
1
嘿,伙计,我明白你的意思。看看我的更新解决方案。我知道这不是一个好方法,但它会起作用,因为默认情况下冻结的对象是不可变的。然而,如果你想继续这个对话,我很乐意。 - BHARATH T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接