为函数提供2个闭包的快速方法

时间:2019-01-05 18:11:22

标签: swift

我有一个具有以下语法的函数:

func myfunc<V1,V2>(to: (V1)->V2, from: (V2)->V1)

并且如您所见,我为此功能提供了2个闭包。 这2个闭包用于将V1转换为V2,反之亦然。请记住,我不能以extensionV1V2的形式提供这些转换。我想提高函数的可用性,我想知道什么是更常见的更好的提供方法这两个是Swift用户。

尽管我有3种方法,每种方法各有优缺点。

第一种方法:使用当前语法。

func myfunc<V1,V2>(to: (V1)->V2, from: (V2)->V1)

优点:用户提供2个闭包,因此他可以更好地组织代码。此外,他可以就地提供它们。

缺点:函数调用将变长,并且只能使用trailing closure进行第二次关闭。

第二种方法:对两者都使用一个闭包,并通过一个参数对其进行区分。

enum ConvertClosure {
   case .to(Any)
   case .from(Any)
}

func myfunc<V1,V2>(operation: (ConvertClosure)->Any)

优点:函数调用变得更加简单,我们也可以使用trailing closure

缺点: 2个关闭的责任现在都在一个,所以变得更加复杂。无法添加泛型检查,需要使用Any作为枚举大小写参数和函数的返回类型。

第三种方法:使用协议而不是闭包。

protocol ConvertOperation {
    associatedtype InVal
    associatedtype OutVal
    func to(_ val: InVal) -> OutVal
    func from(_ val: OutVal) -> InVal
}

func myfunc<V1,V2>(operation: ConvertOperation) 
        where ConvertOperation.InVal == V1, ConvertOperation.OutVal == V2

优点:函数调用变得更加简单。我们从泛型进行类型检查。

缺点:我们需要遵守无法就地完成的协议。方法不是使用闭包,因此可能不是很迅速。

哪种方法更适合Swift用户?您能提出更好的方法吗?

1 个答案:

答案 0 :(得分:2)

这可能是基于观点的,但一般规则是:

  1. 请使用最具体的类型。您希望类型在编译期间为您捕获错误。

  2. 要重用功能时,请使用协议。协议将要求您使用将实现它的结构/类,因此使其更难使用。因此,当您已经有一个符合该协议的对象或功能被重用时,它会更好,因此您可以创建一个对象并多次使用它。

要对您的案件发表更多评论:

  1. 如果存在多个闭包参数,则不应使用结尾的闭包,因为这会影响可读性。但是,这不是一个不好的解决方案,而且很常见。

  2. 这通常是一个不好的解决方案,因为它使用Any类型,它违反了上面的规则1。始终尽量减少使用Any。大多数应用程序都不应该使用它。

  3. 这不是一个不好的解决方案,但是请参见规则2。仅在特定使用情况下,我才是最佳选择。

还要考虑NSObjectAny基本相同。通常,应避免在Swift代码中使用它,因为基本上是在类型检查时辞职。 另请注意,您不应以代码尽可能短为目标。始终以可读性为目标。

在不知道确切用例的情况下,我们可能无法给出更具体的建议。