在Swift协议中添加类型别名约束

4
我该如何表明B.Generator.Element应该是A
protocol SomeProtocol {
    typealias A
    typealias B: CollectionType
    func f(a: A) -> B
}

我意识到我可以执行func f(node: B.Generator.Element) -> B并完全消除A,但如果A在某个其他协议中定义,并且SomeProtocol从中继承,则无法这样做。

编辑:

添加示例

protocol P {
    typealias A
}

protocol Q: P {
    typealias B: CollectionType
    typealias A = B.Generator.Element
    func f(node: A) -> B
}

func g<A, T: Q where A == T.A>(arg1: T, arg2: A) {
    let collection = arg1.f(arg2)
    collection.contains(arg2) // Error here
}
编辑2: 为了澄清,我希望在协议本身中指定A == B.Generator.Element,因为我必须使用一个自由函数。我在开发者论坛中找到了一个线程,正是我的问题。看起来这是当前类型系统的限制。我已经提交了一个radar,希望能解决这个问题 :) 编辑3: 该问题已经有一个radar。在提交时使用rdar://21420236。
1个回答

1
怎么样:
protocol SomeProtocol {
    typealias A = B.Generator.Element
    typealias B: CollectionType
    func f(a: A) -> B
}

编辑:

你遇到的错误是因为不能保证 A (B.Generator.Element) 符合 Equatable。因此,你不能在 collection 上调用 contains,因为 contains 的定义如下:

extension SequenceType where Generator.Element : Equatable {
    public func contains(element: Self.Generator.Element) -> Bool
}

我不确定为什么Xcode将contains呈现为一个有效的调用方法,可能是一个bug...

要解决这个问题,你可以这样做:

// Since you're using Swift 2 you could use a protocol extension instead of a free function.

// Unfortunately, Xcode complains without the explicit declaration that `A` is 
// `B.Generator.Element`.
extension Q where A: Equatable, A == B.Generator.Element {
    func g(elem: A) {
        let collection = f(elem)
        collection.contains(elem)
        ...
    }
}

问题在于A不能保证始终是B.Generator.Element。因此,我无法在B的实例上使用诸如append之类的函数与A的实例一起使用。Xcode正确地将其标记为错误... - Roshan
你觉得你能发布那个例子吗?也许你可以添加更多关于你想要实现的具体细节? - ABakerSmith
这可能实际上是一个错误,需要 A = B.Generator.Element - Kametrixom
谢谢,但我想在协议本身中以某种方式指定 A == B.Generator.Element ,因为我必须使用自由函数。 contains 完全是我的错 - 我把它剥得太干净了。我在开发者论坛中找到了一篇帖子,正好遇到了我的问题。看起来这是当前类型系统的限制。我已经提交了一个反馈,希望能解决 :) - Roshan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接