我很确定这是一个递归错误,它是
Cannot build rewrite system for generic signature; rule length limit exceeded
,它是因为我的代码的这些位而发生的。
extension GenericBuilder where T == SomeUseCase<T.AssociatedEntity> { // <- Error here on this line.
// Do thing, no errors here
}
struct SomeUseCase<T: Entity>: Model {
typealias AssociatedEntity = T
// Do thing, no errors here
}
protocol Entity: Model {
// Do thing, no errors here
}
protocol Model: Equatable, Hashable, Codable {
/// The entity associated with that specific model.
associatedtype AssociatedEntity: Entity
// Do thing, no errors here
}
我不太确定如何解决这个问题,我希望 GenericBuilder 仅当它的
associatedType T
类型为 SomeUseCase
时才具有功能,无论关联的实体如何。我不想为每个可能使用的实体列出 GenericBuilder
的扩展。我希望通过向模型添加 AssociatedEntity
,我可以将类型传入,但现在它爆炸了。
如果我切换到在
T
中使用 GenericBuilder
类型的协议,它会告诉我 any SomeProtocol
不符合 Codable
、Hashable
或 Equatable
,但事实并非如此,特定的实现确实如此,但我希望它适用于每个版本。
有什么建议吗?
您可以在要在扩展中编写的每个方法中编写约束,而不是在扩展声明中编写约束。这样,就可以引入另一个类型参数
U
,解决这个递归约束问题。
假设
GenericBuilder
是:
protocol GenericBuilder {
associatedtype T: Model
}
你可以这样写扩展名:
extension GenericBuilder {
func foo<U: Model>() where
T == SomeUseCase<U>,
U.AssociatedEntity == T.AssociatedEntity {
}
}
这不适用于属性,但属性可以轻松重写为 getter(和 setter)函数,除非您需要从这些属性中获取
KeyPath
。