我应该从文本中提取一些实体(例如,标签,提及等)。为了使事情可重复使用,我创建了一些协议/结构,如下所示:
struct Match {
var value: String
var range: Range<String>
}
protocol Entity {
associatedtype instructions: RegexInstructions
var fullMatch: Match { get }
var partialMatches: [instructions.PartialKeys: Match] { get }
}
// instructions holding keys for regex subgroups and regex string, to understand how an entity should/could be extracted
protocol RegexInstructions {
associatedtype PartialKeys: EntityPartialKeys
var regexString: String { get }
}
typealias EntityPartialKeys = RawRepresentable & Hashable
我有Match
结构,可以容纳正则表达式匹配的值和范围。
协议Entity
是我提取的正则表达式匹配的容器。
这是instructions
关联类型,用于了解如何提取实体以及如何填充其变量。
现在我要创建一些实体:
struct EntityA : Entity {
typealias instructions = InstructionA
var fullMatch: Match
var partialMatches: [instructions.PartialKeys : Match]
}
struct InstructionA: RegexInstructions {
enum PartialKeys: String, EntityPartialKeys {
case x, y, z
}
var regexString: String {
return "A regex string"
}
}
/// and more entities
正则表达式执行服务类是我坚持的地方:
class RegExecuter {
private(set) var registered: [Entity.Type] = [] // ---> Protocol 'Entity' can only be used as a generic constraint because it has Self or associated type requirements
let text: String
init(withTexh text: String) {
self.text = text
}
func register(entityType: Entity.Type) {
registered.append(entityType)
}
func searchAll() -> [Entity] { // ---> Protocol 'Entity' can only be used as a generic constraint because it has Self or associated type requirements
var entitiesFound: [Entity] = [] // ---> Protocol 'Entity' can only be used as a generic constraint because it has Self or associated type requirements
for entityType in registered {
entitiesFound.append(contentsOf: Regex.search(entityType, inText: text)) // here I'm using type.instructions to understand how an entity type could be extracted from text and creating an entity of that type
}
return entitiesFound
}
}
let regExecuter = RegExecuter.init(withText: "a text")
// register needed entities
regExecuter.register(EntityA.self)
regExecuter.register(EntityB.self)
regExecuter.register(EntityC.self)
let foundEntities = regExecuter.searchAll()
我要在此处执行的操作类似于UITableView的UITableViewCell注册。
服务应该知道要搜索的内容(它将搜索某些符合实体协议的对象,但是要搜索哪些对象?)因此,我试图注册实体的Type
,因此服务将知道要搜索的内容,如何搜索以及如何处理找到的匹配项。
由于应该将具有关联类型的协议用作泛型,因此我陷入了困境。从类型擦除到为实体协议创建BaseEntity协议(没有关联类型),我已经尝试了很多方法,以便能够使用向下转换/向上转换,而没有运气。希望有人可以帮助我实现这一目标。