2016-03-02 22 views
2

我试图为我的FieldIdentifiable协议创建一个扩展,只有在实现它的枚举具有Int的RawValue时。唯一的问题是,return FieldIdItem(rawValue: newValue)线不断显示此错误:RawRepresentable上的Swift扩展没有可访问的初始化程序

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

这是一个斯威夫特错误还是我失去了一些东西?

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) 
    } 
} 

回答

6

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

相关类型的SelfFieldIdItem不是(必然) 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 
+0

这工作,是干净的。谢谢! – programmerdave