加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

泛型 – Swift广义存在

发布时间:2020-12-14 05:01:34 所属栏目:百科 来源:网络整理
导读:除了冗余的介绍,我希望有这样的东西: let collection : AnySequence where .Iterator.Element == String = ... 要么 let collection : Sequencewhere .Iterator.Element == String = ... 这在Apple’s Generics Manifesto中被称为“广义存在”.(我认为)我真
除了冗余的介绍,我希望有这样的东西:

let collection : Any<Sequence where .Iterator.Element == String> = ...

要么

let collection : Sequence<where .Iterator.Element == String> = ...

这在Apple’s Generics Manifesto中被称为“广义存在”.(我认为)我真的需要这个用于许多用例和这个:

protocol ‘P’ can only be used as a generic constraint because
it has Self or associated type requirements.

使“第一个面向协议的语言”对我来说很难理解.缺乏这一点使我打击Swift的类型系统并创建不利的通用“抽象”类,其中应该有一个带有关联类型的协议.

这是一个让我受命最多的例子,代表一个泛型类:

protocol GenericClassDelegate : class {
    associatedtype ItemType
    func didDoThat(who : GenericClass<ItemType>) 
}

class GenericClass<T> {
    weak var delegate : GenericClassDelegate<where .ItemType == T>? // can't do that

    func notify() {
        delegate?.didDoThat(who: self)
    }
}

虽然我可以描述GenericClassDelegate协议,但我(当前在Swift 3中)不能拥有该类型的变量或常量(或任何符合限制的类型).

不要将此问题与How to use generic protocol as a variable type或Swift delegate protocol for generic class混淆,因为我的问题是:

>目前有关于将广义存在引入Swift的任何提议或讨论,计划是什么?如果不是,我该如何参与并影响到这一点?
>如果以这种方式设计Swift(使用关联类型,但没有广义存在),也许它意味着一些架构转变.我期望用什么代替委托模式?

附:当你在一个闭包中捕获委托的函数时,不建议使用类型擦除的thunk,这是非常错误和误导,我甚至称之为拐杖.

无意中发现了另一种解决方案,但我对此并不满意:

protocol GenericClassDelegate : class {
    associatedtype ItemType
    func didDoThat(who : GenericClass<ItemType,Self>)
}

class GenericClass<T,Delegate : GenericClassDelegate> where Delegate.ItemType == T {
    weak var delegate : Delegate?

    func notify() {
        delegate?.didDoThat(who: self)
    }

    init(_ delegate : Delegate?) {
        self.delegate = delegate
    }
}

// Delegates must be final classes,otherwise it does not compile
// because I used Self in GenericClassDelegate
final class GenericClassDelegateImp<T> : GenericClassDelegate {
    typealias ItemType = T
    func didDoThat(who: GenericClass<T,GenericClassDelegateImp>) {
        print(who)
    }
}

// Usage:
var delegate = GenericClassDelegateImp<Int>()
var genericClass = GenericClass<Int,GenericClassDelegateImp<Int>>(delegate)

解决方法

Are there any proposals or discussions currently present on introducing Generalized Existentials into Swift,what are the plans? If no,how can I participate and affect this?

这是一个常见的功能,并且已经有关于快速演化的初步设计工作.但此时,核心团队和社区正在关注影响功能的ABI稳定性,或者Lattner将其定义为“Swift 4 Phase 1”.

当第2阶段开始时,你肯定会听到更多关于它的信息.鉴于它的受欢迎程度,它有望成为Swift 4的一部分.

If Swift was designed that way (with Associated Types,but without Generalized Existentials),maybe it implies some architectural shift. What am I expected to replace delegation pattern with?

您可以使用类型擦除的包装器作为传递解决方案.通常,它利用动态分派和类的继承来擦除类型.

protocol Fancy {
    associatedtype Value
    var value: Value
}

struct FancyMatter<Value> {
    let value: Value
}

class AnyFancyBoxBase<P: FancyProtocol>: AnyFancyBox<P.Value> {
    let base: P
    override var value: P.Value { return base.value }
    init(_ base: P) { self.base = base }
}

class AnyFancyBox<Value> {
    var value: Value { fatalError() }
}

var box: AnyFancyBox<Int> = AnyFancyBoxBase(FancyMatter(1))

你可以看看how the Standard Library implements type-erased wrappers.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读