【问题标题】:Referring to own type in Swift?在 Swift 中引用自己的类型?
【发布时间】:2017-07-10 09:34:13
【问题描述】:

在类中,声明闭包参数时如何引用类本身?

在下面的例子中,用什么类型代替Self,这样在构造Foo时,闭包参数也变成FooAnotherFoo也是如此?

class FooBase {
    init(completionHandler: (_ myself : Self)) {
        // ...
        self.completionHandler = completionHandler
    }

    var completionHandler : ((_ :Self) -> Void)?

    func strategyMethod() { ... }
}

class Foo : FooBase {
    // ...
    override func strategyMethod() {
        // do stuff
        completionHandler?(self)
    }
}

class AnotherFoo : FooBase {
    // ...
    override func strategyMethod() {
        // do other stuff
        completionHandler?(self)
    }
}

func useFoos {
    let foo = Foo(completionHandler: {(me : Foo) in
        // ...
    })
    let anotherFoo = AnotherFoo(completionHandler: {(me : AnotherFoo) in
        // ...
    })
}

【问题讨论】:

  • 被连根拔起,因为我认为你做不到。希望这里的真正大师能有更好的答案。就类层次结构而言,这是横向的,对吗?这可以用任何语言完成吗?
  • 相关(欺骗?):Self in init params。但是无论如何你的配置是不安全的——你不可能在非最终类中拥有((Self) -> Void)? 类型的存储属性。在Foo 中,它可以保存(Foo) -> Void 类型的值。但是,如果您随后向上转换为FooBase,它现在静态类型为(FooBase) -> Void,这意味着您可以使用AnotherFoo 参数调用它——这将是非法的(AnotherFooFoo)。
  • 完全正确正确 - 我投了赞成票并且拼写正确使它被连根拔起。道歉。
  • 此功能已记录在此accepted proposal 中,但尚未实现。
  • @Alexander 据我所知,该提案仅旨在将Self 引入类实例成员的主体,以及添加对值类型的支持——我不 相信它涵盖了使用Self作为方法的闭包参数(但我想我们将不得不等待,看看它的实现会带来什么)。

标签: swift generics swift3


【解决方案1】:

我不认为 Swift 允许你做你想做的事,但你可以接近。

使用 FooBase 作为类型,但在传递给 init 函数的闭包中,转换为您知道参数为的类型:

class FooBase {
    init(completionHandler: @escaping (_ myself : FooBase) -> Void) {
        // ...
        self.completionHandler = completionHandler
    }

    var completionHandler : ((_ myself:FooBase) -> Void)?

    func strategyMethod() {
    }
}

class Foo : FooBase {
    // ...
    override func strategyMethod() {
        // do stuff
        completionHandler?(self)
    }
}

class AnotherFoo : FooBase {
    // ...
    override func strategyMethod() {
        // do other stuff
        completionHandler?(self)
    }
}

func useFoos() {
    let foo = Foo(completionHandler: {(myself_in : FooBase) in
        // This cast should always succeed when the closure is used as intended
        if let myself = myself_in as? Foo {
            // ...
        }
    })
    let anotherFoo = AnotherFoo(completionHandler: {(myself_in : FooBase) in
        // This cast should always succeed when the closure is used as intended
        if let myself = myself_in as? AnotherFoo {
            // ...
        }
    })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 2021-08-31
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多