首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在swift中使用协议作为数组类型和函数参数

在swift中使用协议作为数组类型和函数参数
EN

Stack Overflow用户
提问于 2014-07-22 21:21:07
回答 7查看 32.5K关注 0票数 142

我想创建一个可以存储符合特定协议的对象的类。对象应该存储在类型化数组中。根据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)
        }
    }
}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2014-07-22 22:25:42

您遇到了Swift中协议的一个变体问题,目前还没有好的解决方案。

另请参阅Extending Array to check if it is sorted in Swift?,它包含关于如何解决它的建议,这些建议可能适合您的特定问题(您的问题非常通用,也许您可以使用这些答案找到解决方法)。

票数 53
EN

Stack Overflow用户

发布于 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)
        }
    }
}
票数 34
EN

Stack Overflow用户

发布于 2016-07-25 21:47:06

在Swift中,有一类特殊的协议,它不在实现它的类型上提供多态性。此类协议在其定义中使用Selfassociatedtype关键字( 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
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24888560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档