我尝试使用具有关联类型的协议作为类func的返回值。
stackoverflow上的Another post是关于同一个问题的,基于这篇文章的回答,我尝试了以下内容:
// addArg takes a single Int argument and returns something,
// which is capable of adding a another Int argument
class OpWithNoArg {
func addArg<OP: OpWithOneArg where OP.ArgType == Int>(arg: Int) -> OP {
return OpWithOneArgImpl() // (1) error here !
}
}
// a protocol with associated type, which allows adding another
// argument of a not yet specified type
protocol OpWithOneArg {
typealias ArgType
func addAnotherArg(arg: ArgType)
}
// an implementation of the protocol above,
// which fixes the associated type to an Int
class OpWithOneArgImpl : OpWithOneArg {
typealias ArgType = Int
func addAnotherArg(arg: Int) {
// ...
}
}
标有(1)的Xcode 7.0 Beta 4中的错误是
无法转换类型&#39; OpWithOneArgImpl&#39;的返回表达式至 预期回报类型&#39; OP&#39;
如果我将返回值更改为可选,并且返回nil
,则示例将成功编译:
// return null
class OpWithNoArg {
func addArg<OP: OpWithOneArg where OP.ArgType == Int>(arg: Int) -> OP? {
// return OpWithOneArgImpl()
return nil
}
}
这种方式是使用具有关联类型的协议作为swift中的返回值,如果是这样的话,如何修复上面提到的编译器错误?
提前致谢!
修改
在Java中,代码类似于以下代码段。我试图在Swift中找到一种方法来实现同样的目标。
class C {
<T> P<T> f(T arg) {
return new PImpl();
}
}
interface P<S> {
void g(S arg);
}
class PImpl<S> implements P<S> {
PImpl() {}
public void g(S arg) {}
}
答案 0 :(得分:2)
不清楚你想要实现的目标,但是这个错误源于你的addArg
函数中你定义了一个通用类型OP
,它通常应该在函数的参数和正文中使用
相反,您返回非泛型类型,试图强制将其视为通用的“OP。”。
快速修复可能会强制转换为返回对象的OP
:
return OpWithOneArgImpl() as !OP
但我不推荐它。
在您的示例中,addArg
将始终返回OpWithOneArgImpl
,因此可以将其定义为func addArg(arg: Int) -> OpWithOneArgImpl
希望这有帮助。
修改强>
可能这不是你想要达到的目标,但希望它可以提供帮助 更清楚地解释我的意图。
protocol OpWithOneArg {
typealias ArgType
func addAnotherArg(arg: ArgType)
init() // Must have a init with no argument
}
class OpWithOneArgImpl : OpWithOneArg {
typealias ArgType = Int
func addAnotherArg(arg: Int) {
// ...
}
required init() {
// init implementation
}
}
class OpWithNoArg {
func addArgWithOPType<OP: OpWithOneArg where OP.ArgType == Int>(op: OP.Type, arg: Int) -> OP {
return OP() // Here we use the init
}
}
let foo = OpWithNoArg()
foo.addArgWithOPType(OpWithOneArgImpl.self, arg: 3)
修改强>
也许您可能会调查泛型类型的使用:
protocol OpWithOneArg {
typealias ArgType
func addAnotherArg(arg: ArgType)
init() // Must have a init with no argument
}
class OpWithOneArgImpl<T> : OpWithOneArg { // Generic implementation confirming to protocol
typealias ArgType = T
func addAnotherArg(arg: T) {
// ...
}
required init() {
// init implementation
}
}
class OpWithNoArg {
func addArgWithOPType<OP: OpWithOneArg>(op: OP.Type, arg: OP.ArgType) -> OP {
return OP() // Here we use the init
}
}
let foo = OpWithNoArg()
// OpWithOneArgImpl<Int>
foo.addArgWithOPType(OpWithOneArgImpl.self, arg: 3)
// OpWithOneArgImpl<String>
foo.addArgWithOPType(OpWithOneArgImpl.self, arg: "Hello")