1

如何在 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!
  }
}

有一个更好的方法吗?
喜欢?.let{}kotlin 中的语法?

4

3 回答 3

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

函数内部的“ itlet在运行时永远不会为空。

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

于 2021-03-30T16:08:35.670 回答
1

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

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

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

void printBreeds(List<String>? breeds) {
  breeds?.forEach((breed) {
    print(breed);
  });
}
于 2021-03-30T12:17:25.067 回答
0

这个错误是对的 //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);
  });
}

另外,如果我们不想每次都为空操作,我们可以在调用 示例时处理它:

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

输出:

印刷品

于 2021-03-30T12:17:45.590 回答