gpt4 book ai didi

generics - 引用具有关联类型的实例实现协议(protocol)

转载 作者:行者123 更新时间:2023-11-28 09:18:35 24 4
gpt4 key购买 nike

问题

我关注了一个 common pattern by Apple (第 4 次答复)解决通用协议(protocol)缺失的问题:我尝试实现 GeneratorOf<T>/SequenceOf<T> -like 结构,它可以保存对实现我的 ExampleType 的任何实例的引用协议(protocol)。由于协议(protocol)使用关联类型,我不能直接将其用作变量类型,需要一个包装器结构。

在我遇到一个通用函数之前,它工作得很好。我无法创建一个闭包来转发此函数,因此无法像 Apple 在 GeneratorOf<T> 中那样完全实现我的包装器结构。等等。

现状

这是一个简化但不完整的示例,它在 Xcode 6.1 GM 2 上编译良好但缺少通用功能:

protocol ExampleType {

typealias Element

func functionWithElement(element: Element)
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S)
}


struct ExampleOf<T>: ExampleType {

typealias Element = T

private let _functionWithElement: (T) -> ()
// how to declare _functionWithSequence?


init<E: ExampleType where E.Element == T>(_ base: E) {
_functionWithElement = { base.functionWithElement($0) }
// how to assign _functionWithSequence?
}

func functionWithElement(element: Element) {
_functionWithElement(element)
}

func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S) {
// how to call _functionWithSequence?
}
}

朴素的方法

这是它应该的工作方式,但显然在 Swift 中是不可能的。

protocol ExampleType {

typealias Element

func functionWithElement(element: Element)
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S)
}



struct ExampleOf<T>: ExampleType {

typealias Element = T

private let _functionWithElement: (T) -> ()
private let _functionWithSequence: <S: SequenceType where S.Generator.Element == Element>((S) -> ())
// ERROR: Only syntactic function types can be generic


init<E: ExampleType where E.Element == T>(_ base: E) {
_functionWithElement = { base.functionWithElement($0) }
_functionWithSequence = { base.functionWithSequence($0) }
}

func functionWithElement(element: Element) {
_functionWithElement(element)
}

func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S) {
_functionWithSequence(sequence)
}
}

问题

我该如何解决这个限制?
如果只是在 wrapper 内,我不介意在这里和那里进行强制转换。

最佳答案

您所要做的就是用 SequenceOf<T> 包装参数:

protocol ExampleType {
typealias Element

func functionWithElement(element: Element)
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S)
}

struct ExampleOf<T>: ExampleType {

private let _functionWithElement: (T) -> ()
private let _functionWithSequence: (SequenceOf<T>) -> ()

init<E: ExampleType where E.Element == T>(_ base: E) {
_functionWithElement = { base.functionWithElement($0) }
_functionWithSequence = { base.functionWithSequence($0) }
}

func functionWithElement(element: T) {
_functionWithElement(element)
}

func functionWithSequence<S: SequenceType where S.Generator.Element == T>(sequence: S) {
_functionWithSequence(SequenceOf(sequence))
}
}

关于generics - 引用具有关联类型的实例实现协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26363448/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com