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

时间:2021-03-30 12:07:24

标签: flutter dart nullable null-check dart-null-safety

如何在 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 来包围它,你会得到同样的错误:

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>'.
  }
}

如果你创建一个新属性然后空检查它是有效的,但是每次你想空检查时创建新属性变得很麻烦:

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

有没有更好的方法来做到这一点?
喜欢 kotlin 中的 ?.let{} 语法吗?

3 个答案:

答案 0 :(得分:1)

是的,您将创建一个局部变量,就像处理这些事情一样,因为如果您不创建局部变量,那么如果有一个扩展 Dog 类的类可以覆盖 { {1}} 然后即使在您首先检查它之后也可以为空。

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

printBreeds

答案 1 :(得分:1)

为了获得类似于 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”在运行时永远不会为空。

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

答案 2 :(得分:0)

这个错误是正确的public class MyIntentServiceForEmploy extends IntentService { public MyIntentServiceForEmploy() { super("MyIntentServiceForEmploy"); } @Override protected void onHandleIntent(Intent intent) { DatabaseReference reference = firebase.getAllOnlineOrder(); reference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { Toast.makeText(MyIntentServiceForEmploy.this, "notiifiicatiion", Toast.LENGTH_SHORT).show(); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); } }

作为空类型列表传递给函数,该函数表示它接受非空列表

通过以下方式可以访问品种

//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);
  });
}

输出:

印刷品种