RawRepresentable的Swift扩展没有可访问的初始化器。

4

我正在尝试为我的FieldIdentifiable协议创建一个扩展,只有实现它的枚举具有Int类型的RawValue。唯一的问题是return FieldIdItem(rawValue: newValue)这行代码一直显示错误:

'Self.FieldIdItem' cannot be constructed because it has no accessible initializers

这是Swift的一个bug还是我漏了什么?
enum SignUpField: Int, FieldIdentifiable {
  case Email = 0, Password, Username

  typealias FieldIdItem = SignUpField
}

protocol FieldIdentifiable {
  typealias FieldIdItem

  func next() -> FieldIdItem?
  func previous() -> FieldIdItem?
}

extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int {

  func next() -> FieldIdItem? {
    let newValue: Int = self.rawValue+1
    return FieldIdItem(rawValue: newValue)
  }

  func previous() -> FieldIdItem? {
    return FieldIdItem(rawValue: self.rawValue-1)
  }
}
1个回答

11

In

extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int { ... }

Self的相关类型FieldIdItem不一定是RawRepresentable,这就是为什么。

FieldIdItem(rawValue: newValue)

无法编译。您可以通过添加额外的约束条件来修复它:

extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int,
Self.FieldIdItem : RawRepresentable, Self.FieldIdItem.RawValue == Int { ... }

然而,如果 next()previous() 方法实际上应该返回同一类型的实例,则根本不需要关联类型,可以在协议中使用 Self 作为返回类型:

enum SignUpField: Int, FieldIdentifiable {
    case Email = 0, Password, Username
}

protocol FieldIdentifiable {

    func next() -> Self?
    func previous() -> Self?
}

extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int {

    func next() -> Self? {
        return Self(rawValue: self.rawValue + 1)
    }

    func previous() -> Self? {
        return Self(rawValue: self.rawValue - 1)
    }
}

请注意,约束条件也要注意。
Self.RawValue == Int

可以稍微放松一下到
Self.RawValue : IntegerType

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接