我正在实现一个类,该类需要符合如下所示的协议:
protocol P {
func magic<T>(_ thing: Thing, as type: T.Type) -> T
}
此协议由第三方代码提供,这意味着我无法以任何方式对其进行更改以解决此问题。
现在,我有一个通用函数
func magicForObject<T: AnyObject>(_ thing: Thing, as type: T.Type) -> T
,我想从magic
的实现中调用它,只针对实际上是对象的输入thing
。
也就是说,我想做这样的事情:
func magic<T>(_ thing: Thing, as type: T.Type) -> T {
if T.self is AnyClass {
return magicForObject(thing, as: type)
}
else {
// do something else
}
}
但是我找不到任何方法可以完成这项工作。上面的代码显然不会编译,类似
的东西也不会编译if let T_ = T.self as? AnyClass { ... }
因为T_
只是一个普通变量,而不是通用参数(可能是编译时)。
我也尝试这样做:
func magic<T: AnyObject>(_ thing: Thing, as type: T.Type) -> T { ... }
func magic<T>(_ thing: Thing, as type: T.Type) -> T { ... }
并分别实现两者。如果直接在对象上调用受约束的AnyObject
,则正确调用该函数;而当对象强制转换为协议类型P
时,则不是;在这种情况下,第二个是一直使用。
这种情况似乎无可救药地受到限制,但是有没有我没有想到的解决方法?
看起来这在Swift中目前是不可能的。我在Swift论坛上做了一个post pitching the idea;如果您也需要此功能,请随时鸣叫。
答案 0 :(得分:1)
您的示例很难处理,因此我不得不做很多假设,但是我想这应该满足您的要求。
根据您所说的,您具有给定的协议P:
protocol P {
func magic<T>(_ thing: Thing, as type: T.Type) -> T
}
让P默认实现您需要执行的操作:
extension P {
// Implementation for magic where T is a class
func magic<T>(_ thing: Thing, as type: T.Type) -> T where T: AnyObject {
print("AnyObject Called")
return Test2() as! T
}
// Implementation for magic where T is a struct
func magic<T>(_ thing: Thing, as type: T.Type) -> T {
print("Struct Called")
return Test() as! T
}
}
您有一个符合P
的课程class Test2: P {
}
让我们假设您拥有这个Thing对象和一个我们想要传递的结构,以查看我们是否具有正确的结果:
class Thing {
}
struct Test {
}
现在让我们测试是否在magic
上调用Test2
,是否将根据传递给type
的内容magic
调用正确的函数
let test = Test()
let test2 = Test2()
// T is Test2 so its a class
test2.magic(Thing(), as: Test2.self)
// T is Test so its a struct
test2.magic(Thing(), as: Test.self)
打印输出调用
AnyObject Called
Struct Called
似乎您可以为structs
做某事,为classes
做另一件事