gpt4 book ai didi

Swift - 继承协议(protocol)关联类型删除

转载 作者:行者123 更新时间:2023-11-30 11:43:23 26 4
gpt4 key购买 nike

我有 3 个协议(protocol)和一个必须确定最专业协议(protocol)的函数

protocol Super {}
protocol Sub1: Super { associatedtype T }
protocol Sub2: Super {}

func test(_ s: Super) { ... do stuff }

现在我已经尝试过类型删除

class AnySub<E>: Sub1 {
typealias T = E
// ... standard type erasure init
}

进行以下更改:

protocol Super {
func tryAsSub1() -> AnySub? {}
}
extension Sub1 {
func tryAsSub1() -> AnySub<T> { return AnySub<T>() }
}
extension Sub2 {
func tryAsSub1() -> AnySub { return nil }
}
func test(_ s: Super) {
if let sub1 = s.tryAsSub1() { ... do stuff for Sub1 }
else let sub2 = s as? Sub2 { ... do stuff for Sub2 }
}

但这显然不起作用,因为我在 Super 和 Sub2 中没有任何通用参数。有人知道我该如何解决这个问题吗?

最佳答案

由于 Sub1 使用关联类型,因此您无法在运行时确定某个变量是否属于该类型。类型橡皮擦在一定程度上有帮助,但是很难使用多种橡皮擦类型。我的建议是为您需要处理的每种类型重载 test 方法。这也为您的代码增加了更多的类型安全性。

func test<S: Sub1, T>(_ s: S) where S.T == T

func test(_ s: Sub2)

但是,对于拥有 Super 元素集合并且需要根据实际类型执行一些操作的情况,上述解决方案将不起作用。对于这种情况,一种可能的方法是在协议(protocol)级别移动 test 方法,并在子协议(protocol)中覆盖。

protocol Super {
func test()
}

protocol Sub1: Super { associatedtype T }

protocol Sub2: Super {}

extension Sub1 {
func test() { ... do stuff for Sub1 }
}

extension Sub2 {
func test() { ... do stuff for Sub2 }
}

缺点是符合者可以覆盖test,因此你会失去原始的实现。

关于Swift - 继承协议(protocol)关联类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49092320/

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