Swift 如何实现类型擦除的泛型包装器?
我需要为自己的结构实现一个类型擦除包装器,非常类似于Swift 如何实现类型擦除的泛型包装器?,swift,generics,Swift,Generics,我需要为自己的结构实现一个类型擦除包装器,非常类似于SequenceOf,GeneratorOf,等等。因此我开始尝试自己重新实现标准的SequenceOf 我刚刚复制并粘贴了SequenceOf的声明,将其重命名为MySequenceOf,并填写了一些存根以获得: /// A type-erased sequence. /// /// Forwards operations to an arbitrary underlying sequence with the /// same `Eleme
SequenceOf
,GeneratorOf
,等等。因此我开始尝试自己重新实现标准的SequenceOf
我刚刚复制并粘贴了SequenceOf
的声明,将其重命名为MySequenceOf
,并填写了一些存根以获得:
/// A type-erased sequence.
///
/// Forwards operations to an arbitrary underlying sequence with the
/// same `Element` type, hiding the specifics of the underlying
/// sequence type.
///
/// See also: `GeneratorOf<T>`.
struct MySequenceOf<T> : SequenceType {
/// Construct an instance whose `generate()` method forwards to
/// `makeUnderlyingGenerator`
init<G : GeneratorType where T == T>(_ makeUnderlyingGenerator: () -> G) {
fatalError("implement me")
}
/// Construct an instance whose `generate()` method forwards to
/// that of `base`.
init<S : SequenceType where T == T>(_ base: S) {
fatalError("implement me")
}
/// Return a *generator* over the elements of this *sequence*.
///
/// Complexity: O(1)
func generate() -> GeneratorOf<T> {
fatalError("implement me")
}
}
现在,非常简单,我只需要从初始化器中挂起makeUnderlineGenerator
,然后从generate()
调用它:
struct MySequenceOf:SequenceType{
let maker:()->GeneratorOf
init(uu-makeUnderlineGenerator:()->G){
self.maker={return makeUnderlyingGenerator()}
}
func generate()->GeneratorOf{
return self.maker()
}
}
但这给了我一个错误:“'G'不能转换为'GeneratorOf'”
如果我强制执行强制转换,它会编译:
struct MySequenceOf<T> : SequenceType {
let maker: ()->GeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
self.maker = { return makeUnderlyingGenerator() as GeneratorOf<T> }
}
func generate() -> GeneratorOf<T> {
return self.maker()
}
}
struct MySequenceOf:SequenceType{
let maker:()->GeneratorOf
init(uu-makeUnderlineGenerator:()->G){
self.maker={返回makeUnderlineGenerator()作为GeneratorOf}
}
func generate()->GeneratorOf{
return self.maker()
}
}
但是它在运行时从动态强制转换中崩溃
那么如何实现这样的类型擦除呢?这一定是可能的,因为Swift标准库做了大量的工作(SequenceOf、GeneratorOf、SinkOf)。下面是一个
MySequenceOf
的示例实现,它似乎可以工作:
struct MySequenceOf<T> : SequenceType {
let myGenerator : GeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
self.myGenerator = GeneratorOf( makeUnderlyingGenerator() )
}
init<S : SequenceType where S.Generator.Element == T>(_ base: S) {
self.myGenerator = GeneratorOf( base.generate() )
}
func generate() -> GeneratorOf<T> {
return myGenerator
}
}
所以(据我所知,我还远远没有理解所有的泛型序列
“诀窍”是
生成器是捕获给定生成器的闭包,因此可以
转发next()
调用。不需要强制转换。尝试:
struct MySequenceOf<T> : SequenceType {
private let _generate:() -> MyGeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
_generate = { MyGeneratorOf(makeUnderlyingGenerator()) }
}
init<S : SequenceType where S.Generator.Element == T>(_ base: S) {
_generate = { MyGeneratorOf(base.generate()) }
}
func generate() -> MyGeneratorOf<T> {
return _generate()
}
}
struct MyGeneratorOf<T> : GeneratorType, SequenceType {
private let _next:() -> T?
init(_ nextElement: () -> T?) {
_next = nextElement
}
init<G : GeneratorType where G.Element == T>(var _ base: G) {
_next = { base.next() }
}
mutating func next() -> T? {
return _next()
}
func generate() -> MyGeneratorOf<T> {
return self
}
}
struct MySequenceOf:SequenceType{
私有let_generate:()->MyGeneratorOf
init(uu-makeUnderlineGenerator:()->G){
_generate={MyGeneratorOf(makeunderyinggenerator())}
}
初始值(u基:S){
_generate={MyGeneratorOf(base.generate())}
}
func generate()->MyGeneratorOf{
返回_生成()
}
}
结构MyGeneratorOf:GeneratorType,SequenceType{
私人出租下一个:()->T?
init(uuTelement:()->T?){
_下一步=下一步
}
初始值(变量u基:G){
_next={base.next()}
}
突变func next()->T{
返回_next()
}
func generate()->MyGeneratorOf{
回归自我
}
}
实现ProtocolOf
的基本策略如下:
protocol ProtocolType {
typealias Value
func methodA() -> Value
func methodB(arg:Value) -> Bool
}
struct ProtocolOf<T>:ProtocolType {
private let _methodA: () -> T
private let _methodB: (T) -> Bool
init<B:ProtocolType where B.Value == T>(_ base:B) {
_methodA = { base.methodA() }
_methodB = { base.methodB($0) }
}
func methodA() -> T { return _methodA() }
func methodB(arg:T) -> Bool { return _methodB(arg) }
}
协议协议类型{
类型别名值
func methodA()->Value
func方法B(参数:值)->Bool
}
结构原型:原型{
私人出租方法A:()->T
私人出租方式B:(T)->Bool
初始(uu基:B){
_methodA={base.methodA()}
_methodB={base.methodB($0)}
}
func methodA()->T{return_methodA()}
func methodB(arg:T)->Bool{return_methodB(arg)}
}
在回复@MartinR的评论中添加了 _generate是闭包而不是生成器本身,这有什么特殊原因吗 首先,我认为,这是一个规范或语义的问题 不用说,区别在于“何时创建生成器” 考虑以下代码:
class Foo:SequenceType {
var vals:[Int] = [1,2,3]
func generate() -> Array<Int>.Generator {
return vals.generate()
}
}
let foo = Foo()
let seq = MySequenceOf(foo)
foo.vals = [4,5,6]
let result = Array(seq)
class Foo:SequenceType{
var VAL:[Int]=[1,2,3]
func generate()->Array.Generator{
返回vals.generate()
}
}
设foo=foo()
设seq=MySequenceOf(foo)
foo.vals=[4,5,6]
让结果=数组(seq)
问题是:
结果
应该是[1,2,3]
还是[4,5,6]
?我的MySequenceOf
和内置的SequenceOf
会产生后者。我只是将这些行为与内置行为进行了匹配。尝试为您的类型定义Generator typealias。”因此,我假设Xcode生成的SequenceOf的“where T==T”约束声明实际上意味着“where G.Element==T”是的,在Xcode中显示声明的方式是一个众所周知的错误。你实际上不能说,其中t==t
,Swift标题也不能说。我花了很长时间才想出我的答案,但我必须承认你的答案看起来更整洁。“是否有特殊原因使\u generate
是一个闭包,而不是生成器本身(如我的代码中所示)?@MartinR补充到了答案中。作为旁注,请参见以下内容:
struct MyGeneratorOf<T> : GeneratorType, SequenceType {
var nextFunc : () -> T?
init<G : GeneratorType where G.Element == T>(_ base: G) {
self.nextFunc = {
() -> T? in
var generator = base
return generator.next()
}
}
init(_ nextElement: () -> T?) {
self.nextFunc = nextElement
}
mutating func next() -> T? {
return nextFunc()
}
// Returns a copy of itself.
func generate() -> MyGeneratorOf<T> {
return MyGeneratorOf(nextFunc)
}
}
struct MySequenceOf<T> : SequenceType {
private let _generate:() -> MyGeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
_generate = { MyGeneratorOf(makeUnderlyingGenerator()) }
}
init<S : SequenceType where S.Generator.Element == T>(_ base: S) {
_generate = { MyGeneratorOf(base.generate()) }
}
func generate() -> MyGeneratorOf<T> {
return _generate()
}
}
struct MyGeneratorOf<T> : GeneratorType, SequenceType {
private let _next:() -> T?
init(_ nextElement: () -> T?) {
_next = nextElement
}
init<G : GeneratorType where G.Element == T>(var _ base: G) {
_next = { base.next() }
}
mutating func next() -> T? {
return _next()
}
func generate() -> MyGeneratorOf<T> {
return self
}
}
protocol ProtocolType {
typealias Value
func methodA() -> Value
func methodB(arg:Value) -> Bool
}
struct ProtocolOf<T>:ProtocolType {
private let _methodA: () -> T
private let _methodB: (T) -> Bool
init<B:ProtocolType where B.Value == T>(_ base:B) {
_methodA = { base.methodA() }
_methodB = { base.methodB($0) }
}
func methodA() -> T { return _methodA() }
func methodB(arg:T) -> Bool { return _methodB(arg) }
}
class Foo:SequenceType {
var vals:[Int] = [1,2,3]
func generate() -> Array<Int>.Generator {
return vals.generate()
}
}
let foo = Foo()
let seq = MySequenceOf(foo)
foo.vals = [4,5,6]
let result = Array(seq)