如何确保始终推断出不可为 null 的类型?

Gui*_*lla 2 generics dart

我目前正在制作一个 API,我希望 type 的可选值永远T不能为空(当然启用空安全)。

让我们用以下例子来举例说明:

void main() {
  T nonNullableGeneric<T>(T value) {
    if(value == null) {
      throw 'This is null';
    }

    return value;
  }

  nonNullableGeneric(1); // Works fine
  
  nonNullableGeneric(null); // Works fine BUT I would like that the type inference would not allow a nullable value

  // Now this works as expected:
  // "the argument type 'Null' can't be assigned to the parameter type 'int'."
  // 
  // ... but I have to specify the type `T`, which is not clear given my function signature, that clearly
  // requires a non-nullable value of type `T`
  nonNullableGeneric<int>(null);
  
  // How can I make the following call:
  // nonNullableGeneric(null)
  // to throw me something like "the argument type 'Null' can't be assigned to a parameter type 'T'."?
}
Run Code Online (Sandbox Code Playgroud)

我还创建了一个dartpad

Null 正如您所看到的,如果我想确保在使用泛型参数时不能指定类型,则必须始终指定类型。

我怎样才能确保它永远不会允许可为空的类型?

Gui*_*lla 6

我发现答案非常明显,尽管我认为无论如何提及都是合理的:只需将类型T约束(扩展)为Object. 这将确保该特定参数永远不会是可选的。

引用Object文档:

/// ...
/// Because `Object` is a root of the non-nullable Dart class hierarchy,
/// every other non-`Null` Dart class is a subclass of `Object`.
/// ...
Run Code Online (Sandbox Code Playgroud)

因此,在我提到的这个例子中,解决方案是:

void main() {
  T nonNullableGeneric<T extends Object>(T value) {
    return value;
  }

  nonNullableGeneric(1); // Works fine
   
  // Throws a:
  // Couldn't infer type parameter 'T'. Tried to infer 'Null' for 'T' which doesn't work: Type parameter 'T' declared to extend 'Object'.
  // The type 'Null' was inferred from: Parameter 'value' declared as 'T' but argument is 'Null'.
  // Consider passing explicit type argument(s) to the generic
  nonNullableGeneric(null);
}
Run Code Online (Sandbox Code Playgroud)