如何在颤动中创建空安全块?

How to create null safe block in flutter?

如何在 Flutter 中进行空检查或创建空安全块?

这是一个例子:

class Dog {
  final List<String>? breeds;
  Dog(this.breeds);
}

void handleDog(Dog dog) {
    printBreeds(dog.breeds); //Error: The argument type 'List<String>?' can't be assigned to the parameter type 'List<String>'.
}

void printBreeds(List<String> breeds) {
  breeds.forEach((breed) {
    print(breed);
  });
}

如果你尝试用 if case 包围它,你会得到同样的错误:

void handleDog(Dog dog){
  if(dog.breeds != null) {
    printBreeds(dog.breeds); //Error: The argument type 'List<String>?' can't be assigned to the parameter type 'List<String>'.
  }
}

如果你创建一个新的 属性 然后进行 null 检查它可以工作,但是每次你想进行 null 检查时创建新属性会变得很麻烦:

void handleDog(Dog dog) {
  final List<String>? breeds = dog.breeds;
  if (breeds != null) {
    printBreeds(breeds); // OK!
  }
}

有更好的方法吗?
就像 kotlin 中的 ?.let{} 语法?

是的,您将创建一个局部变量,就像处理这些事情一样,因为如果您不创建局部变量,那么如果有 class 扩展 Dog class 可以覆盖 breeds ,即使您首先检查了它,它也会变得可以为空。

您可以尝试的另一个解决方案是在 printBreeds 方法中将 List<String> 更改为可为空。

void handleDog(Dog dog) {
  printBreeds(dog.breeds);
}

void printBreeds(List<String>? breeds) {
  breeds?.forEach((breed) {
    print(breed);
  });
}

这个错误是对的//Error: The argument type 'List<String>?' can't be assigned to the parameter type 'List<String>'.

因为 null 类型列表正在传递给表示它接受非 null 列表的函数

通过以下方式可以获得品种

void printBreeds(List<String>? breeds) {
  breeds?.forEach((breed) {
    print(breed);
  });
}

另外,如果不想每次都进行nullable操作,可以边调用边处理 示例:

class Dog {
  final List<String>? breeds;
  Dog(this.breeds);
}

void handleDog(Dog dog) {
    print("handleDog");
    printBreeds(dog.breeds!);  
}
// This method only called if breeds not null
void printBreeds(List<String> breeds) {
  print("printBreeds");
  breeds.forEach((breed) {
    print(breed);
  });
}

void main() {
  var dog = Dog(null);
   handleDog(dog);
}

输出:

打印品种

为了获得类似于 Kotlins 的东西 .let{} 我创建了以下通用扩展:

extension NullSafeBlock<T> on T? {
  void let(Function(T it) runnable) {
    final instance = this;
    if (instance != null) {
      runnable(instance);
    }
  }
}

并且可以这样使用:

void handleDog(Dog dog) {
  dog.breeds?.let((it) => printBreeds(it));
}

"it" 在 let 函数中永远不会在运行时为 null。

感谢所有建议,但它们都是将空检查进一步向下移动到代码执行的一些变体,这不是我想要的。