gpt4 book ai didi

swift - 为什么要限制带有 Self 或 associatedtype 的协议(protocol)?

转载 作者:行者123 更新时间:2023-11-28 08:08:37 25 4
gpt4 key购买 nike

在设计 API 时,我在每个角落都会遇到这个问题:

Protocol can only be used as a generic constraint because it has Self or associatedType requirements

这意味着如果您计划单独使用协议(protocol)类型,您基本上不能在协议(protocol)级别使用 Selfassociatedtype —— 否则需要类型本身是通用的级联失控。

这很烦人(阅读:几乎不可能设计合理的 API,例如公开协议(protocol)但隐藏实现)。例如,你不能有一个简单的数据容器协议(protocol):

protocol DataContainer: Equatable {
var id: Int { get }
var content: Data { get }
}

问题是 Equatable 需要静态函数 ==,当然,它是使用 Self 表示的。因此,您不能拥有像 [DataContainer] 这样的类型,或任何数量的其他自然事物。我首先遇到了用户组(数组)(可能是三种不同类型之一)。

“官方”推荐的“解决方案”是使用委托(delegate)/包装结构来消除类型变量,例如 AnyDataContainer。这感觉像是一个相当愚蠢的变通方法,不是正确的 API 设计。

老实说,我不明白为什么类型系统有这个限制。原因是什么?为什么编译器不能为每个协议(protocol) P 隐式创建 AnyP 来绕过它?

最佳答案

这是我能想到的一个原因,实际上也不需要神秘的设置。基于问题中的示例,假设我们可以有这样的代码:

func contained(element: DataContainer, in list: [DataContainer]) -> Bool {
for elem in list {
if elem == element {
return true
}
}
return false
}

Swift 编译器想要静态分派(dispatch) ==;但它不能!它没有可以选择的单一实现;每个数组元素都可能有自己的类型,因此 == 的实现,而 element 可能有一个完全不同的类型。因此,编译器禁止使用手头的代码。


另外两个想法。

  1. 我认为编译器过于具有防御性。下面的代码可以很容易地编译,例如:

    func contained(id: Int, in list: [DataContainer]) -> Bool {
    for elem in list {
    if elem.id == id {
    return true
    }
    }
    return false
    }

    在这里,我们不需要知道数组元素的确切类型;他们每个人都有一个 Int 属性 id 的 promise 就足够了!

    因此它可以允许使用像 [DataContainer] 这样的类型,只要所有访问的属性都可以静态解析。

  2. 如果在何处分派(dispatch)和/或存在通用实现没有歧义,编译器可以允许 Self 引用。例如(伪代码):

    extension DataContainer {
    static func ==<T: DataCointainer, U: DataContainer>(lhs: T, rhs:U) -> Bool {
    guard T == U else {
    return false
    }

    return T.==(lhs, rhs as! T)
    }
    }

    这样的默认实现可以在上述使用上下文中使用,即如果没有足够的类型信息可用于静态选择实现。

我不知道是否可以通过类似的想法解决通用协议(protocol)的所有问题,以及我们是否会在此过程中遇到进一步的限制。

关于swift - 为什么要限制带有 Self 或 associatedtype 的协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44389942/

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