这是我的简化代码:
class MyClass {
func returnSomething(argument: Protocol2) {}
}
protocol Protocol2: Protocol1 where E == Int {
}
protocol Protocol1 {
associatedtype E
func doSomething(_ value: E)
}
编译器给出了以下错误:Protocol 'Protocol2' can only be used as a generic constraint because it has Self or associated type requirements
。
我知道在协议可以用作函数中的参数之前需要解析关联的类型E,但鉴于Protocol2提供了该信息,为什么我仍然无法编译该代码?
答案 0 :(得分:3)
由于我正在学习Swift泛型,所以我想试一试:
如果要在函数Protocol2
中使用returnSomething
作为参数类型
正如@Nicolas Miari所建议的
class MyClass {
func returnSomething<T: Protocol2>(argument: T) {}
}
现在顾名思义这个函数应该返回一些东西
所以
class MyClass {
func returnSomething<T: Protocol2>(argument: T) -> T {
return argument
}
}
我在原始问题中看到的另一个问题是使用where
子句
我想您想说Protocol1
的相关类型是Int
你应该这样做
protocol Protocol2: Protocol1 {
typealias E = Int
}
答案 1 :(得分:0)
&#34;如何使用关联类型协议作为函数的参数类型?&#34;
我可能不会按照您在此处提出的要求,但如果您的协议具有关联类型,例如
protocol DummyNumericTypeWrapper {
associatedtype U: Numeric
static func magic(_ bar: U) -> U
}
您可以访问此类型,例如在通用上下文中,通用占位符已被约束到您的协议。要使用完全虚拟的示例跟进上面的虚拟包装器,例如:
extension StupidNumericTypeWrapper where U == Int {
static func magic(_ bar: Int) -> Int {
return bar + 42
}
}
func foo<T: StupidNumericTypeWrapper>(_ bar: T.U, _ _ : T.Type) -> T.U {
return T.magic(bar) * T.magic(bar)
}
struct DefaultMagic: StupidNumericTypeWrapper { }
let num = foo(1, DefaultMagic.self)
print(num) // 1849 (43*43)
答案 2 :(得分:0)
Swift编译器将typealias
转换为where
子句。 (Typealias覆盖关联类型&#39; E&#39;来自协议&#39; Protocol1&#39;更好地表示为协议上的相同类型约束)
传递参数确实适用于上述语法,谢谢大家!
但是,如何返回符合Protocol2
的实例?
class ClassConformsToProto2: Protocol2 {
func doSomething(_ value: Int) {
}
}
class MyClass {
func returnSomething<T: Protocol2>() -> T {
return ClassConformsToProto2()
}
}
此代码无效。
无法转换类型&#39; ClasConformsToProto2&#39;的返回表达式返回类型&#39; T&#39;