swift - 有没有办法指定一个只接受两种特定类型之一的通用函数?

标签 swift generics types protocols

除了处理两种不同的类型外,我有几个相同的函数。我希望让我的代码更加干燥,所以我想将它们变成两种类型的一个函数。但我该怎么做呢?

我知道如何创建通用函数:func doSomething<T>(arg: T) { ... }

我也知道如何创建一个只接受特定协议(protocol)对象的通用函数:

func doSomething<T: Event>(arg: T) { ... }

现在我已经解决了这个小问题,当时我想要一个可以接受字符串和符合事件协议(protocol)的对象的函数。在那种情况下,我通过使 String 符合 Event 协议(protocol)很容易地解决了这个问题,如下所示:extension String: Event {} . (无论如何,事件是一个空协议(protocol))

但这次我要处理的两种类型是 StringEvent.Type .在那种情况下,我不能使用相同的技巧,因为元类型不能扩展或用于扩展其他类型。

有没有办法写这样的东西?

func doSomething<T where T == Event.Type || T == String>(arg: T) { ... }

编辑,我会解释更多为什么我这样做:

我正在编写一个事件调度程序。事件可以是像“user.birthday”这样的带有负载的字符串,也可以是符合事件协议(protocol)的对象。我想两者都支持,因为不同的开发者有不同的偏好。所以我可以像这样定义事件和监听器:

struct UserWonAward: Event {
    let user: User
}

events.listenTo("user.birthday") {
    (user: User) in
    print("Happy birthday \(user.name)!")
}

events.listenTo {
    (event: UserWonAward) in
    print("Congratulations \(event.user.name)!")
}

现在我需要帮助的事情来了。有时我会在队列中排列一些事件,然后刷新特定类型的队列,如下所示:

let user1 = User(name: "John Doe")
let user2 = User(name: "Jane Doe")

events.queue("user.birthday", payload: user1)
events.queue("user.birthday", payload: user2)

events.queue(UserWonAward(user: user1))
events.queue(UserWonAward(user: user2))

// Some time later

events.flushQueueOf("user.birthday")
events.flushQueueOf(UserWonAward)

如您所见,在 flushQueueOf() 中方法我可以输入 StringEvent.Type .现在我已经为此编写了两个单独的方法,但是这两个方法中的代码几乎相同,所以我真的想将它们合并为一个方法。

最佳答案

没有。

您可以有类型intersections - 即“与”逻辑(类型由多个类型绑定(bind)),但不能有并集 - 即“或”你想要的逻辑。

仔细一想,也没什么意义,尤其是java的类型安全。

如果您的方法适用于两种类型中的任何一种,并且您想遵循 DRY:

public void method(TypeA x) {
    methodAnyType(x);
}

public void method(TypeB x) {
    methodAnyType(x);
}

private void methodAnyType(Object x) {
    // x is either TypeA or TypeB
}

关于swift - 有没有办法指定一个只接受两种特定类型之一的通用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36272014/

相关文章:

swift - 倒带时自动重新加载 TableViewController

c# - 拦截泛型类中的方法调用

objective-c - 在类型为父类(super class)的变量上调用子类方法

java - 棘手的 Java 泛型 : generic class implementing non generic interface with generic Method

java - 什么时候在 Java 中使用泛型类合适

scala - Seq、SeqLike、GenSeq 还是 GenSeqLike?

PostgreSQL 到 Java 数据类型 (Grails)

swift - 如何使用 Swift 更改 iOS 警告消息框标题和消息中的字体大小

swift - 如何在显示屏幕保护程序时唤醒应用程序

ios - Int 类型的表达式模式不能匹配 (int) -> Int 类型的值