有没有办法指定只接受两种特定类型之一的泛型函数?

时间:2016-03-28 22:04:19

标签: swift generics types protocols

我有一些相同的功能,除了它们处理两种不同类型的事实。我希望保持我的代码更干,所以我想把它们变成两种类型的函数。但是我该怎么做?

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

我也知道如何创建只接受某个协议对象的通用函数:

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

现在我已经解决了这个小问题,之前我想要一个能接受Strings和符合Event协议的对象的函数。在这种情况下,我很容易通过使String符合事件协议来解决它:extension String: Event {}。 (无论如何,事件是一个空的协议)

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

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

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

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

我正在写一个事件调度员。事件可以是类似“user.birthday”的字符串,伴随有效负载或符合事件协议的对象。我想支持两者,因为不同的开发者有不同的偏好。所以我可以像这样定义事件和听众:

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。现在我已经为此编写了两个单独的方法,但这两个方法中的代码几乎完全相同,所以我真的想将它们合并到一个方法中。

1 个答案:

答案 0 :(得分:1)

没有

您可以输入十字路口 - 即&#34;和&#34;逻辑(类型由多种类型绑定),但您不能拥有 union - 即&#34;或&#34;像你想要的逻辑。

如果你考虑一下,它没有意义,特别是对于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
}