RawRepresentable上的Swift扩展没有可访问的初始化程序

pro*_*ave 4 generics enums swift swift-extensions swift-protocols

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

'Self.FieldIdItem' cannot be constructed because it has no accessible initializers
Run Code Online (Sandbox Code Playgroud)

这是一个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)
  }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 10

extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int { ... }
Run Code Online (Sandbox Code Playgroud)

相关类型FieldIdItemSelf不是(必然) RawRepresentable,这就是为什么

FieldIdItem(rawValue: newValue)
Run Code Online (Sandbox Code Playgroud)

不编译.您可以通过添加其他约束来解决此问题:

extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int,
Self.FieldIdItem : RawRepresentable, Self.FieldIdItem.RawValue == Int { ... }
Run Code Online (Sandbox Code Playgroud)

但是,如果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)
    }
}
Run Code Online (Sandbox Code Playgroud)

还要注意约束

Self.RawValue == Int
Run Code Online (Sandbox Code Playgroud)

可以稍微放松一下

Self.RawValue : IntegerType
Run Code Online (Sandbox Code Playgroud)