在 Dart 中区分 undefined 和 null

TSR*_*TSR 5 dart flutter

考虑以下函数:

 BasicClass copyWith({
    String id,
  }) {
   // some code behaving differently for 1) id is undefined and 2) id is explicit null
  }
Run Code Online (Sandbox Code Playgroud)

并考虑以下两个参数:

  1. 没有(id 未定义)

    复制();

  2. 空(id 为空)

    copyWith(id: null);

在 copyWith 方法中,有什么方法可以让它在 1) 和 2) 中表现不同

Rém*_*let 7

没有办法区分null“没有传递参数”。

唯一的解决方法( Freezed使用它来生成支持的 copyWith null)是使用自定义默认值进行作弊:

final undefined = Object();

class Example {
  Example({this.param});
  final String param;

  Example copyWith({Object param = undefined}) {
    return Example(
      param: param == undefined ? this.param : param as String,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这需要像这样输入变量Object

要解决该问题,您可以使用继承将其隐藏Object在类型安全的接口下(再次参见Freezed):

final undefined = Object();

class Example {
  Example._();
  factory Example({String param}) = _Example;
  
  String get param;

  void method() {
    print('$param');
  }

  Example copyWith({String param});
}

class _Example extends Example {
  _Example({this.param}): super._();

  final String param;

  @override
  Example copyWith({Object param = undefined}) {
    return Example(
      param: param == undefined ? this.param : param as String,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是对简单的 `undefined !==null // true` (在 js 中)这样的黑客攻击 (3认同)
  • 我们应该扩展“null”对象来携带“isImplicit”信息。对于任何声明为无值的变量,此布尔值默认为“true”,并且当未传递任何参数时,当该值显式设置为 null 时,此布尔值为“false”。要阅读它,我们可以添加一个内置函数,例如:“bool isImplicitNull(myVar)”或一些新语法。这将节省大量的样板文件和像这样的疯狂黑客(并且不需要 JS 中著名的令人困惑的“未定义”) (2认同)