在 Swift 中指定协议之间的关系
Specify relationships between protocols in Swift
我想指定一个协议来管理一些符合另一个协议的类型对象。像这样:
// Specify protocol
protocol ElementGenerator {
func getElements() -> [Element]
}
protocol Element {
// ...
}
// Implement
class FooElementGenerator: ElementGenerator {
func getElements() -> [FooElement] {
// Generate elements here
return [FooElement()]
}
}
class FooElement {
// ...
}
尝试编译时,出现错误:
Type 'FooElementGenerator' does not conform to protocol 'ElementGenerator'
暗示候选人 func getElements() -> [FooElement]
具有不匹配的类型 () -> [FooElement]
,但它期望 () -> [Element]
.
如何修复这种错误?
更新:
此解决方案似乎有效:
protocol ElementGenerator {
typealias T:Element
func getElements() -> [T]
}
protocol Element {
// ...
}
class FooElementGenerator: ElementGenerator {
typealias T = FooElement
func getElements() -> [T] {
return [T()]
}
}
class FooElement: Element {
// ...
}
但是当我尝试创建这样的变量时:
let a: ElementGenerator = FooElementGenerator()
出现新错误:
Protocol 'ElementGenerator' can only be used as a generic constraint because it has Self or associated type requirements
实现协议方法时,return 类型必须相同,但您可以 return 子对象 class 像这样;
protocol ElementGenerator {
func getElements() -> [Element]
}
//@objc for bridging in objective C
@objc protocol Element {
// ...
}
// Implement
class FooElementGenerator: NSObject,ElementGenerator {
override init() {
super.init();
//--
let fooElements:[FooElement] = self.getElements() as! [FooElement]
}
func getElements() -> [Element] {
// Generate elements here
return [FooElement()]
}
}
class FooElement:NSObject, Element {
// ...
override init() {
super.init();
//--
NSLog("FooElement init");
}
}
第二种情况的错误信息是因为你定义了ElementGenerator
一个“关联类型”,这意味着你只能用它来给出类型的约束。
例如,如果您需要为通用 ElementGenerator
值定义一个函数,您可以这样写:
func f<T1:ElementGenerator>(elemGenerator:T1) -> Element {
return elemGenerator.getElements()[0]
}
var a : Element = FooElementGenerator()
var b : Element = BarElementGenerator()
var x : Element = f(a)
var y : Element = f(b)
var z : FooElement = f(a) as! FooElement
我想指定一个协议来管理一些符合另一个协议的类型对象。像这样:
// Specify protocol
protocol ElementGenerator {
func getElements() -> [Element]
}
protocol Element {
// ...
}
// Implement
class FooElementGenerator: ElementGenerator {
func getElements() -> [FooElement] {
// Generate elements here
return [FooElement()]
}
}
class FooElement {
// ...
}
尝试编译时,出现错误:
Type 'FooElementGenerator' does not conform to protocol 'ElementGenerator'
暗示候选人 func getElements() -> [FooElement]
具有不匹配的类型 () -> [FooElement]
,但它期望 () -> [Element]
.
如何修复这种错误?
更新:
此解决方案似乎有效:
protocol ElementGenerator {
typealias T:Element
func getElements() -> [T]
}
protocol Element {
// ...
}
class FooElementGenerator: ElementGenerator {
typealias T = FooElement
func getElements() -> [T] {
return [T()]
}
}
class FooElement: Element {
// ...
}
但是当我尝试创建这样的变量时:
let a: ElementGenerator = FooElementGenerator()
出现新错误:
Protocol 'ElementGenerator' can only be used as a generic constraint because it has Self or associated type requirements
实现协议方法时,return 类型必须相同,但您可以 return 子对象 class 像这样;
protocol ElementGenerator {
func getElements() -> [Element]
}
//@objc for bridging in objective C
@objc protocol Element {
// ...
}
// Implement
class FooElementGenerator: NSObject,ElementGenerator {
override init() {
super.init();
//--
let fooElements:[FooElement] = self.getElements() as! [FooElement]
}
func getElements() -> [Element] {
// Generate elements here
return [FooElement()]
}
}
class FooElement:NSObject, Element {
// ...
override init() {
super.init();
//--
NSLog("FooElement init");
}
}
第二种情况的错误信息是因为你定义了ElementGenerator
一个“关联类型”,这意味着你只能用它来给出类型的约束。
例如,如果您需要为通用 ElementGenerator
值定义一个函数,您可以这样写:
func f<T1:ElementGenerator>(elemGenerator:T1) -> Element {
return elemGenerator.getElements()[0]
}
var a : Element = FooElementGenerator()
var b : Element = BarElementGenerator()
var x : Element = f(a)
var y : Element = f(b)
var z : FooElement = f(a) as! FooElement