【问题标题】:Identifying a function with a return type of void in runtime在运行时识别返回类型为 void 的函数
【发布时间】:2021-07-25 01:45:13
【问题描述】:

我有一个函数,它接受另一个函数及其参数作为参数。函数的返回类型及其参数类型是未知的。我需要在运行时知道参数函数是否返回一个值或者它是否是一个 void 函数。

functionHandler(Function fn, List<dynamic> args) {
  var result = fn(args[0], args[1]);
  if ( -- fn returns a value --)
    doSomething();
  else if ( -- fn is a void function --)
    doSomethingElse();
}

我不能使用 fn.runtimeType 因为参数类型未知。

void 函数将返回 null,但我无法区分 void 函数和仅返回 null 值的函数。

如果 fn 是返回类型为 void 的函数,我有什么方法可以在运行时检查?

【问题讨论】:

  • 你真的需要区分void和非void函数吗?如果您打算返回 result,无论返回类型如何,您都可以这样做。
  • 另外,void 函数也可以(遗憾地)返回非null 值。它们通常不应该,但如果您将void foo() =&gt; something(); 写为void foo() { something(); } 的简写,您实际上会返回something(); 的结果。

标签: dart


【解决方案1】:

使用fn.runtimeType.toString().endsWith('=&gt; void') 是一种老生常谈的方法。

既然您似乎知道 fn 恰好采用两个位置参数,更好的方法是使 functionHandler 成为泛型函数,使用参数化类型完全限定您的 Function 类型,然后检查类型参数返回类型:

dynamic functionHandler<ReturnType, ArgumentType1, ArgumentType2>(
  ReturnType Function(ArgumentType1, ArgumentType2) fn,
  List<dynamic> args,
) {
  // `ReturnType == void` is a syntax error, so we must do a little
  // dance to get its corresponding `Type` object.
  Type getType<T>() => T;

  if (ReturnType == getType<void>()) {
    print('void');
  } else {
    print('non-void');
  }
}

void main() {
  // Test a `void` function.
  void voidFunction(Object arg1, dynamic arg2) {}
  functionHandler(voidFunction, []); // Prints: void

  // Test a function that returns `null`.
  Null nullFunction(int arg1, String? arg2) => null;
  functionHandler(nullFunction, []); // Prints: non-void

  // Test a function with optional arguments.
  int intFunction(int arg1, [int? arg2, int? arg3]) => 0;
  functionHandler(intFunction, []); // Prints: non-void
}

【讨论】:

  • 使用Type.toString 假定用于toString 的函数类型对象的语法,这是未指定的,并且在历史上跨平台并不一致。它还给出了void Function() Function(int, int) 的误报。取决于类型参数仅在推断类型参数时才有效。如果显式调用functionHandler&lt;Object?, Never, Never&gt;(anyFunction);,则看不到anyFunction 的返回类型。不过,我没有严格的更好方法:)
猜你喜欢
  • 2015-03-24
  • 1970-01-01
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
  • 1970-01-01
相关资源
最近更新 更多