我想创建一个可以存储符合特定协议的对象的类。对象应该存储在类型化数组中。根据Swift文档协议可以用作类型:
因为它是一种类型,所以您可以在许多允许其他类型的地方使用协议,包括:
但是,以下代码会生成编译器错误:
协议“”SomeProtocol“”只能用作泛型约束,因为它具有自身或关联的类型要求
你应该如何解决这个问题:
protocol SomeProtocol: Equatable {
func bla()
}
class SomeClass {
var protocols = [SomeProtocol]()
func addElement(element: SomeProtocol) {
self.protocols.append(element)
}
func removeElement(element: SomeProtocol) {
if let index = find(self.protocols, element) {
self.protocols.removeAtIndex(index)
}
}
}
发布于 2014-07-22 22:25:42
您遇到了Swift中协议的一个变体问题,目前还没有好的解决方案。
另请参阅Extending Array to check if it is sorted in Swift?,它包含关于如何解决它的建议,这些建议可能适合您的特定问题(您的问题非常通用,也许您可以使用这些答案找到解决方法)。
发布于 2014-07-22 21:54:59
您希望创建一个泛型类,其类型约束要求与其一起使用的类符合SomeProtocol
,如下所示:
class SomeClass<T: SomeProtocol> {
typealias ElementType = T
var protocols = [ElementType]()
func addElement(element: ElementType) {
self.protocols.append(element)
}
func removeElement(element: ElementType) {
if let index = find(self.protocols, element) {
self.protocols.removeAtIndex(index)
}
}
}
发布于 2016-07-25 21:47:06
在Swift中,有一类特殊的协议,它不在实现它的类型上提供多态性。此类协议在其定义中使用Self
或associatedtype
关键字( Equatable
是其中之一)。
在某些情况下,可以使用类型擦除的包装器来使集合同态。下面是一个例子。
// This protocol doesn't provide polymorphism over the types which implement it.
protocol X: Equatable {
var x: Int { get }
}
// We can't use such protocols as types, only as generic-constraints.
func ==<T: X>(a: T, b: T) -> Bool {
return a.x == b.x
}
// A type-erased wrapper can help overcome this limitation in some cases.
struct AnyX {
private let _x: () -> Int
var x: Int { return _x() }
init<T: X>(_ some: T) {
_x = { some.x }
}
}
// Usage Example
struct XY: X {
var x: Int
var y: Int
}
struct XZ: X {
var x: Int
var z: Int
}
let xy = XY(x: 1, y: 2)
let xz = XZ(x: 3, z: 4)
//let xs = [xy, xz] // error
let xs = [AnyX(xy), AnyX(xz)]
xs.forEach { print($0.x) } // 1 3
https://stackoverflow.com/questions/24888560
复制相似问题