gpt4 book ai didi

swift - 类型 'T' 不符合协议(protocol) 'EntityType'

转载 作者:搜寻专家 更新时间:2023-10-31 19:35:01 28 4
gpt4 key购买 nike

我认为这里的类型关系相当简单,但我遗漏了错误的原因。错误是:“类型‘T’不符合协议(protocol)‘EntityType’”(在 ThingManager):

//
protocol EntityType {
typealias Identifier
var identifier : Identifier { get }
}

class EntityWithStringIdentifier : EntityType {
var identifier : String
init (i:String) { self.identifier = i }
}

class Thing : EntityWithStringIdentifier {}

//
protocol EntityManager {
typealias Entity : EntityType
func has (entity:Entity) -> Bool
}

class BaseEntityManager<Entity:EntityType> : EntityManager {
func has (entity:Entity) -> Bool { return true }
}

// Type 'T' does not conform to protocol 'EntityType'
class ThingManager<T:Thing> : BaseEntityManager<T> {
}

TThing 的子类型; ThingEntityWithStringIdentifier 的子类型,它实现了 EntityType那么,为什么会出错

显然这个错误可以通过使用来避免:

class ThingManager<T:Thing where T:EntityType> : BaseEntityManager<T> {
}

然后可以用 Thing 实例化一个 ThingManager(暗示 Thing 首先实现了 EntityType。 ..)

var tm = ThingManager<Thing>()

从类型的角度来看,是否有更好的方法来实现这种 DAO 模式?

最佳答案

随着 Swift 2.0 的发布,用 Swift 的早期版本来回答这个问题似乎毫无意义,因为它很快就会过时。我可以确认这个问题——我认为这是一个错误——在撰写本文时在 Swift 2.0 中仍然存在。但是,我可以建议一种稍微不同的组织代码的方法,该方法可以缓解问题,同时仍然具有干净的实现:跳过 ThingManager 类并改用协议(protocol)扩展。

因此,将所有代码都保留到 BaseEntityManager,您将拥有:

// NOTE "where Entity: Thing". This is the key.
extension EntityManager where Entity: Thing {
func useAThing(thing: Thing) {

}
}

let tm = BaseEntityManager<Thing>()
tm.useAThing(Thing(i: "thing"))

我怀疑这最终会成为做事的“快捷方式”。 Swift 的泛型对我来说简直就是陌生。他们经常违反恕我直言的最小意外原则。但如果你了解他们的怪癖,他们最终会非常强大。这种方法的唯一缺点是访问修饰符和封装。 useAThing 方法无法访问 EntityManagerBase 的私有(private)状态,这可能是问题,也可能不是问题,具体取决于您的情况。

最后,如果您采用这种方法,我建议您进行一些重命名。 BaseEntityManager 如果您从不子类化它,感觉就像是错误的名称。相反,我将其称为 EntityManager 并将协议(protocol)重命名为 EntityManagerType 以遵循 Apple 的约定。

关于swift - 类型 'T' 不符合协议(protocol) 'EntityType',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30676412/

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