如何修复错误“无法为通用签名构建重写系统;快速超出规则长度限制?

问题描述 投票:0回答:1

我很确定这是一个递归错误,它是

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
,但事实并非如此,特定的实现确实如此,但我希望它适用于每个版本。

有什么建议吗?

swift generics recursion types
1个回答
0
投票

您可以在要在扩展中编写的每个方法中编写约束,而不是在扩展声明中编写约束。这样,就可以引入另一个类型参数

U
,解决这个递归约束问题。

假设

GenericBuilder
是:

protocol GenericBuilder {
    associatedtype T: Model
}

你可以这样写扩展名:

extension GenericBuilder {
    func foo<U: Model>() where 
        T == SomeUseCase<U>,
        U.AssociatedEntity == T.AssociatedEntity {
        
    }
}

这不适用于属性,但属性可以轻松重写为 getter(和 setter)函数,除非您需要从这些属性中获取

KeyPath

© www.soinside.com 2019 - 2024. All rights reserved.