简体   繁体   English

在 dart/flutter 中指定回调 function 接受两组可能的参数

[英]Specify callback function in dart/flutter that accepts two possible sets of parameters

Is there a way to create a callback function that accepts one of two different sets of parameters?有没有办法创建一个接受两组不同参数之一的回调 function? Or have two separate callback functions as options, and make sure at least one of them is specified?或者有两个单独的回调函数作为选项,并确保至少指定其中一个

I have a view that I want to pass a callback function, that either includes a Goal or a title and description (which would end up being put together into a goal).我有一个观点,我想传递一个回调 function,其中包括一个Goaltitledescription (最终将被组合成一个目标)。

void Function({required String title, String? description}) onGoalPopupCompletionWithString;

void Function({required Goal goal}) onGoalPopupCompletionWithGoal;

I want one, but not both of these callbacks to be required - if there is a function with a goal as a parameter, I'd execute that, but if not, I'd execute the one with a String title and a String description.我想要一个,但不是这两个回调都需要 - 如果有一个 function 以目标作为参数,我会执行它,但如果没有,我会执行一个带有字符串标题和字符串描述的回调. Something like this:像这样的东西:

if (onGoalPopupCompletionWithGoal != null) {
    // execute this callback function
} else {
    // execute onGoalPopupCompletionWithString
}

That's not something which can be expressed in the Dart type system.这不是 Dart 类型系统可以表达的东西。

A single function which can be called as void Function({required String title, String? description}) or void Function({required Goal goal}) will have a signature of:单个 function 可以称为void Function({required String title, String? description})void Function({required Goal goal})将具有以下签名:

  void Function({String title, String? description, Goal goal})

Any implementation of that type will either have to make title and goal optional, or provide them with default values.该类型的任何实现要么必须使titlegoal可选,要么为它们提供默认值。 In either case, there is no way, in the type system, to ensure that the function is always invoked as one of the original types.无论哪种情况,在类型系统中都无法确保 function 始终作为原始类型之一被调用。

Also, it'll be highly annoying to write, you'd probably be better off with two different callbacks.此外,编写起来会非常烦人,使用两个不同的回调可能会更好。

You can provide two callback parameters, one of each kind, and require that at least one of them is required... but not in the type system.您可以提供两个回调参数,每种一个,并要求其中至少一个是必需的……但不是在类型系统中。 You'd have to make both optional, and check at runtime that at least one was provided.您必须将两者都设为可选,并在运行时检查是否提供了至少一个。

Having as single parameter which accepts either function type, that requires a union type.具有接受 function 类型的单个参数,这需要联合类型。 A union type allows either one type or another, in this case either void Function({required String title, String? description}) or void Function({required Goal goal}) .联合类型允许使用一种类型或另一种类型,在这种情况下为void Function({required String title, String? description})void Function({required Goal goal}) Dart does not have union types in general. Dart 一般没有联合类型。

If you need to pass both of these types through the same currently valid Dart type, the type needs to be a supertype of both.如果您需要通过相同的当前有效 Dart 类型传递这两种类型,则该类型需要是两者的超类型。 The closest common supertype of those two types is Function .这两种类型中最接近的常见超类型是Function

(The only function types that void Function({required Goal goal}) can be assigned to are void Function({required X goal}) where X is a subtype of Goal . I guess you can also change the void to another, equivalent, top-type. Any other function type allows its functions to be called in a way that void Function({required Goal goal}) does not.) (唯一可以分配void Function({required Goal goal})的 function 类型是void Function({required X goal})其中XGoal的子类型。我想您也可以将void更改为另一个等效的,顶级类型。任何其他 function 类型都允许以void Function({required Goal goal})不允许的方式调用其函数。)

Dart does have one kind of type union: Classes with subclasses. Dart 确实有一种类型联合:带有子类的类。 You can declare a callback class:您可以声明一个回调 class:

abstract class MyCallback {
}
class TitleCallback extends Callback {
  final void Function({required String title, String? description}) callback;
  TitleCallback(this.callback);
}  
class GoalCallback extends Callback {
  final void Function({required Goal goal}) callback;
  GoalCallback(this.callback);
}  

Then you can require one such callback, and dispatch on it as necessary.然后你可以要求一个这样的回调,并在必要时调度它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM