#dart
Вопрос:
У меня есть функция, которая принимает другую функцию и ее аргументы в качестве аргументов. Тип возвращаемой функции и типы ее параметров неизвестны. Мне нужно знать во время выполнения, возвращает ли функция аргумента значение или это функция 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?
Комментарии:
1. Действительно ли вам нужно различать
void
функции и неvoid
функции? Если вы намерены вернутьсяresult
, вы можете сделать это независимо от типа возврата.2. Кроме того,
void
функции также могут (к сожалению) возвращать не —null
значения. Как правило, они не должны , но если вы пишетеvoid foo() => something();
как сокращениеvoid foo() { something(); }
, вы фактически возвращаете результатsomething();
.
Ответ №1:
Хакерским способом было бы использовать fn.runtimeType.toString().endsWith('=> 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
}
Комментарии:
1. Использование
Type.toString
предполагает синтаксис, используемый дляtoString
Type
объектов типов функций, который не указан и исторически не был согласован между платформами. Это также дает ложный положительный результат дляvoid Function() Function(int, int)
. В зависимости от параметра типа работает только в том случае, если выводятся аргументы типа. Если вы явно вызоветеfunctionHandler<Object?, Never, Never>(anyFunction);
, вы не увидите возвращаемый типanyFunction
. Тем не менее, у меня нет строго лучшего подхода 🙂