具有最终计算默认值的Dart类

g6ll5ycj  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(112)

我在应用程序中有一个设备类,其中一个属性需要计算和最终,加上一些可以在构造函数中设置或具有默认值的属性。代码如下:

class Device {
  String idx;
  String id; 
  String name; 
  String icon; 
  int order; 

  // have to create the idx before initializing the object because I can't
  // figure out how to do that here.
  Device(
      {required this.idx,
      required this.id,
      required this.name,
      this.icon = 'none',
      this.order = -1});

  // Creates a device from a JSON string
  factory Device.fromJson(Map<String, dynamic> jsonData) {
    return Device(
        idx: jsonData['idx'],
        id: jsonData['id'],
        name: jsonData['name'],
        icon: jsonData['icon'],
        order: jsonData['order']);
  }

  // Returns the device as a String
  static Map<String, dynamic> toMap(Device device) => {
        'idx': device.idx,
        'id': device.id,
        'name': device.name,
        'icon': device.icon,
        'order': device.order
      };
}

基本上,我试图为对象设置一个唯一的索引,这样在我的对象列表中,我可以清楚地识别一个特定的设备。我使用Uuid包为idx生成一个UUID
我今天唯一能做到这一点的方法是在我的其他代码中创建idx,创建对象并将其传入。我在这里读了很多文章,讨论了解决这个问题的不同方法,我知道我必须将idx值设置为常量,但我不知道如何做到这一点,并调用Uuid库。
我知道它看起来像这样:

Device(
      {this.idx = const <<some calculation/expression>>,
      required this.id,
      required this.name,
      this.icon = 'none',
      this.order = -1});

删除required修饰符,并在赋值之前添加const。我没有尝试过调用Uuid方法。有人能帮助我理解如何做到这一点吗?
根据@jamesdlin的答案更新代码:

import 'package:uuid/uuid.dart';

const uuid = Uuid();

class Device {
  String idx;
  String id;
  String name;
  String icon;
  int order;

  Device(
      {String? idx,
      required this.id,
      required this.name,
      this.icon = 'none',
      this.order = -1})
      : idx = idx ?? uuid.v1();

  // Creates a device object from a JSON string
  factory Device.fromJson(Map<String, dynamic> jsonData) {
    return Device(
        idx: jsonData['idx'],
        id: jsonData['id'],
        name: jsonData['name'],
        icon: jsonData['icon'],
        order: jsonData['order']);
  }

  // Returns the device object as a String
  static Map<String, dynamic> toMap(Device device) => {
        'idx': device.idx,
        'id': device.id,
        'name': device.name,
        'icon': device.icon,
        'order': device.order
      };
}

这是可行的,但是我从来没有一个用例需要手动设置idx,那么我该如何完成呢?我可以这样做,但是我真的想更好地理解如何做我需要的事情。

dzjeubhm

dzjeubhm1#

我今天能做到这一点的唯一方法是在创建对象的其他代码中创建idx并将其传入。
如果你希望对象能够生成自己的UUID,你可以这样做:

const uuid = Uuid();

class Device {
  String idx = uuid.v1(); // Or whatever UUID version you want.
  ...

或者,如果你希望调用者可以选择传入一个UUID字符串,你可以使用the typical technique of using null to achieve non- const default function arguments

const uuid = Uuid();

class Device
  String idx;

  Device({String? idx, ...})
    : idx = idx ?? uuid.v1(),
      ...

const意味着该对象是一个 * 编译时常量 *,此外,const对象是规范化的,因此生成UUID的假设const表达式最终将为每个Device生成相同的String,这与unique相反。

更新您更新的问题

这是可行的,但是我从来没有一个用例需要手动设置idx,那么我该如何实现呢?我可以这样做,但是我真的想更好地理解如何做我需要的事情。
我不明白您的意思,因为您显然有手动设置idx的用例(你的Device.fromJson工厂构造函数)。如果你的意思是你没有一个用例可以让Device类外部的代码手动设置idx,然后你可以添加一个带有idx参数的私有构造函数和一个不带idx参数的公共构造函数:

class Device {
  String idx;
  String id;
  String name;
  String icon;
  int order;

  Device({
    required String id,
    required String name,
    String icon = 'none',
    int order = -1,
  }) : this._(
          idx: uuid.v1(),
          id: id,
          name: name,
          icon: icon,
          order: order,
        );

  Device._({
    required this.idx,
    required this.id,
    required this.name,
    required this.icon,
    required this.order,
  });

  // Creates a device object from a JSON string
  factory Device.fromJson(Map<String, dynamic> jsonData) {
    return Device._(
        idx: jsonData['idx'],
        id: jsonData['id'],
        name: jsonData['name'],
        icon: jsonData['icon'],
        order: jsonData['order']);
  }
}

或者,由于idx不是final.fromJson可以为它分配一个值:

factory Device.fromJson(Map<String, dynamic> jsonData) {
    return Device(
        id: jsonData['id'],
        name: jsonData['name'],
        icon: jsonData['icon'],
        order: jsonData['order'])
      ..idx = jsonData['idx'];
  }

相关问题