Dart:构造函数的传播算子

时间:2019-03-07 10:34:49

标签: constructor properties dart flutter spread-syntax

在我的 flutter 应用中,我具有以下小部件:

Container(
  decoration: BoxDecoration(
    border: Border.all(
      color: Colors.red,
      width: 2,
      style: BorderStyle.solid,
    ),
  ),
  child: Text('Container 1'),
)
Container(
  decoration: BoxDecoration(
    border: Border(
      top: BorderSide(
        color: Colors.red,
        width: 2,
        style: BorderStyle.solid,
      ),
    ),
  ),
  child: Text('Container 2'),
)

它们的边界使用相同的属性。所以我想知道是否有 spread-operator -like 方式为两个小部件插入相同的属性?也许像:

const borderBase = (
  color: Colors.red,
  width: 2,
  style: BorderStyle.solid,
)

Container(
  decoration: BoxDecoration(
    border: Border.all(
      ...borderBase,
    ),
  ),
  child: Text('Container 1'),
)

Container(
  decoration: BoxDecoration(
    border: Border(
      top: BorderSide(
        ...borderBase,
      ),
    ),
  ),
  child: Text('Container 2'),
)

5 个答案:

答案 0 :(得分:2)

没有这样的东西。

正在开发一个散布运算符,但是它仅用于列表,而不是类(https://github.com/dart-lang/language/issues/47

答案 1 :(得分:2)

您可以执行以下操作:

const BorderSide borderBase = BorderSide(
  color: Colors.red,
  width: 2,
  style: BorderStyle.solid,
);

Container(
  decoration: BoxDecoration(
    border: Border.all(
      color: borderBase.color,
      width: borderBase.width,
      style: borderBase.style,
    ),
  ),
  child: Text('Container 1'),
)

Container(
  decoration: BoxDecoration(
    border: Border(
      top: borderBase,
    ),
  ),
  child: Text('Container 2'),
)

不是最好的,但是仍然可以重用。

答案 2 :(得分:1)

这是我穷人的传播算子模式的虚拟样本:

我为经常经过细微修改的类创建了一个复制构造函数。 在定义期间这是额外的工作,但是在使用这些类时,它会在许多位置带来回报。可以通过子类化在标准类上使用相同的模式-只是为了连接到特定的问题。

python.exe odoo-bin scaffold my_module

答案 3 :(得分:0)

现在dart同时具有散布运算符和class extensions,您可以滥用这两者来向...spread方法中添加static支持。尽管我怀疑这是个好主意,但我还是进行了dartpadgist)的演示。最终结果类似于:

final Border spreadBorder = Border.fromSides([
  ...Border(
    left: BorderSide(color: Colors.pink),
    right: BorderSide(color: Colors.pinkAccent),
  ).sides,
  ...Border(
    top: BorderSide(color: Colors.blue),
    bottom: BorderSide(color: Colors.blueAccent),
  ).sides,
]).scale(5);

enum _Side { top, right, bottom, left }

extension SpreadBorder on Border {
  Iterable<MapEntry<_Side, BorderSide>> get sides {
    return () sync* {
      if (top != BorderSide.none) {
        yield MapEntry(_Side.top, top);
      }
      // ...other yields
    }();
  }

  static Border fromSides(Iterable<MapEntry<_Side, BorderSide>> parts) {
    BorderSide top, right, bottom, left;

    for (final borderPart in parts) {
      switch (borderPart.key) {
        case _Side.top:
          top = borderPart.value;
          break;
        // ... other cases
      }
    }
    return Border(
      top: top,
      right: right,
      bottom: bottom,
      left: left,
    );
  }
}

答案 4 :(得分:0)

展开运算符将适用于地图,例如Map<String, dynamic> 所以对我有用的是将对象转换为 json,即 Map<String, dynamic>,使用扩展运算符,然后转换回对象。

你可以试试这样的:

class Something {
  final String id;
  final String name;
  
  Something({required this.id, required this.name});

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

  Map<String, dynamic?> toJson() {
    return {
    'id': id,
    'name': name
    };
  }

}


final x = Something(id: 'abc', name: 'def');
final y = Something.fromJson({...x.toJson(), 'name': 'somethingElse'})

这可能非常昂贵,但如果您只关心使用扩展运算符,这应该可以完成工作。