【发布时间】:2015-08-18 02:56:33
【问题描述】:
这可能吗?
场景是,我希望一个函数接受一个与该函数的通用约束无关的参数,并返回依赖于所述参数的未知类型的结果。这些类型之间没有任何关系。一个可能是字符串,一个可能是 int,一个可能是字符串数组等。
我在协议中使用 typealias 对此进行了实验,每个符合它的对象都设置了自己的类型,并在其工作中使用类型别名。
我已经将此作为协议进行了实验:
protocol BaseFunctionality {
typealias ReturnType
var property: ReturnType { get set }
func getData() -> ReturnType
}
然后我有几个符合要求的类:
class StringClass: BaseFunctionality {
typealias ReturnType = String
var property: ReturnType = "HELLO WORLD"
func getData() -> ReturnType {
return property
}
}
和
class IntClass: BaseFunctionality {
typealias ReturnType = Int
var property: ReturnType = 12345
func getData() -> ReturnType {
return property
}
}
所以,我想出的是这样的:
func getIt<T: BaseFunctionality>(int: Int) -> T.ReturnType {
if (int == 0) {
let stringClass = StringClass()
return stringClass.getData() as! T.ReturnType // for some reason I have to as! this
} else {
let intClass = IntClass()
return intClass.getData() as! T.ReturnType // same as above comment
}
}
并这样称呼它:
let testing = getIt(1)
但是,我收到一条错误消息,
“无法使用类型为 '(int)' 的参数列表调用 'getIt'”。
我知道编译器在确定我到底想要什么作为返回类型时遇到问题,所以我想提供一个闭包,将T: BaseFunctionality 映射到它所拥有的属性。
func getIt<T:BaseFunctionality, U where U == T.ReturnType>(int:Int, unwrapType: T -> U ) -> U {
if (int == 0) {
let source = StringClass()
return unwrapType(source as! T) // for some reason, source is not a valid T
}
else {
let source = IntClass()
return unwrapType(source as! T) // see above comment
}
}
签名中U 的约束可能有问题,但我已经尝试了各种......
例如,我这样称呼它。
let data = getIt(1, mapToType: {(unwrapType) -> String in
return unwrapType.property as String
})
但是,这会导致操场上发生疯狂的事情......(崩溃)
有没有人知道如何在编译时使用未知的返回类型来实现这个神奇的功能?
这里是 swiftstub:http://swiftstub.com/800198020/?v=beta
谢谢!
【问题讨论】:
标签: swift generics protocols factory swift2