具有相关类型的对象/结构数组

时间:2018-08-13 10:42:56

标签: ios arrays swift swift-protocols associated-types

我应该从文本中提取一些实体(例如,标签,提及等)。为了使事情可重复使用,我创建了一些协议/结构,如下所示:

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协议(没有关联类型),我已经尝试了很多方法,以便能够使用向下转换/向上转换,而没有运气。希望有人可以帮助我实现这一目标。

0 个答案:

没有答案