Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何实现类型擦除的泛型包装器?_Swift_Generics - Fatal编程技术网

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)