如果值为 null,则不执行赋值

Don't execute assignment if value is null

我仍在跟上 dart 的步伐,想知道是否有更简单的方法可以在值为 null 时不执行语句。请参见下面的示例:

我总是可以执行下面的 if 语句来设置 field3 和 field4,但感觉像 field5 这样的东西应该可以工作。但是当我尝试这样做时,它会抱怨对空值使用了空检查运算符。

我也不想将地图更改为具有动态值。

是否有一个单一的衬里来做我想做的事情,或者我只需要在设置值之前检查是否为 null。

  Map<String, Object> myMap = {};

  print('running now');
  try {
    myMap['field1'] = DummyClass.getString('hello');
    myMap['field2'] = DummyClass.getString('good');

    //Is there a more concise way to do this than the 2 options below?

    if (DummyClass.getOptionalString('goodbye') != null) {
      myMap['field3'] = DummyClass.getOptionalString('goodbye')!;
    }

    String? temp = DummyClass.getOptionalString('go');
    if (temp != null) {
      myMap['field4'] = temp;
    }

    // This gives an error 'null check operator used on a null value'
    // myMap['field5'] ??= DummyClass.getOptionalString('to')!;

  } catch (e) {
    print('error condition, $e');
  }

  print(myMap);
}

class DummyClass {

  static String getString(String? strParam) {
    String? retString = getOptionalString(strParam);
    if (retString == null) {
      throw ('nulls are not allowed');
    }
    return retString;
  }

  static String? getOptionalString(String? strParam) {
    if (strParam == null || strParam.length < 3) {
      return null;
    }
    return strParam;
  }
}

问题是 ??= 运算符在它为 null 时赋值给左边。展开后,它看起来像这样:

a ??= b;

// Equivalent to:

if (a == null) {
  a = b;
}

这不是您要实现的目标。 AFAIK,Dart 中还没有这样的运算符。不过,你可以试试这个:

final possiblyNullValue = '';
final myMap = <String, String>{};

myMap['key'] = possiblyNullValue ?? myMap['key'];

// Equivalent to:

if (possiblyNullValue != null) {
  myMap['key'] = possiblyNullValue;
}

// or:

myMap['key'] = possiblyNullValue != null? possiblyNullValue : myMap['key'];

在您的情况下,one-liner。

您可以创建包含所有条目(甚至是空值)的地图,然后过滤掉空值:

void main() {
  try {
    final myMap = <String, dynamic>{
      'field1': DummyClass.getString('hello'),
      'field2': DummyClass.getString('good'),
      'field3': DummyClass.getOptionalString('goodbye'),
      'field4': DummyClass.getOptionalString('go'),
    }..removeWhere((k, v) => v == null);
    print(myMap);
  } catch (e) {
    print('error condition, $e');
  }
}

没有 built-in 方法可以做你想做的事,但你可以编写一个函数(或扩展方法)来做。例如:

extension MapTrySet<K, V> on Map<K, V> {
  void trySet(K key, V? value) {
    if (value != null) {
      this[key] = value;
    }
  }
}

然后你可以做:

myMap.trySet('field3', DummyClass.getOptionalString('goodbye'));
myMap.trySet('field4', DummyClass.getOptionalString('go'));

或者,如果您真的想使用普通的 Map 语法,您可以创建自己的 Map class,它具有 void operator []=(K key, V? value) 覆盖并且在valuenull,但这可能不值得付出努力。