我有一个通用协议,它有一个返回泛型参数的方法。协议有两种实现,它们都将字符串作为返回类型。我想要一个方法来构建一个类似于基于某个参数的类集群的特定实例。该方法约束泛型类型,但尝试返回时出错:
"无法将StringReturn类型的返回表达式转换为返回类型T"
protocol GenericProtocol {
typealias ReturnType
func doSomething() -> ReturnType
}
struct StringReturn : GenericProtocol {
func doSomething() -> String {
return "first"
}
}
struct AnotherStringReturn : GenericProtocol {
func doSomething() -> String {
return "another"
}
}
func build<T : GenericProtocol where T.ReturnType == String>(param: String) -> T {
if .. {
return StringReturn()
} else {
return AnotherStringReturn
}
}
答案 0 :(得分:1)
您要实现的是使用泛型函数使用Swift的类型约束来创建对象的实例。
请注意Apple文档中的一般语法:
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // function body goes here }
在你的函数中,不可能在函数执行时推断出T
是什么类型,因为你没有将它作为参数传递给函数,因此你不能说是什么类型的输出
如果要使用带有类型约束的泛型函数,可以在协议中添加一些init
并使用如下函数:
func build<T : GenericProtocol where T.ReturnType == String>(object: T.Type, param: String) -> T {
// Your code here
return T.init()
}
let str = build(StringReturn.self, param: "name")
希望它有所帮助!
答案 1 :(得分:0)
在最新的 Swift 版本中可以使用不透明类型而不是协议泛型来实现。
斯威夫特 5.3
<块引用>您可以将不透明类型视为泛型类型的反面。泛型类型让调用函数的代码以一种从函数实现中抽象出来的方式为该函数的参数和返回值选择类型。例如,以下代码中的函数返回一个依赖于其调用者的类型:
protocol Fighter { }
struct XWing: Fighter { }
func launchFighter() -> Fighter {
XWing()
}
let red5 = launchFighter()
它需要在您的协议名称之前使用关键字some:
func launchOpaqueFighter() -> some Fighter {
XWing()
}