Swift Generics,Stucts和Protocol:没有可访问的初始化器

时间:2015-10-01 09:08:53

标签: generics struct protocols swift2 xcode7

为什么这段代码没有编译?

编译错误在struct FirmDecoder"返回Firm()"。

错误消息是:'公司'无法构造,因为它没有可访问的初始化器。

//: Playground - noun: a place where people can play
import UIKit
protocol EntityDecoder {
  func decode<U>(json: [String:AnyObject], index: Int) -> U
}

public struct Firm {
  public init(){}
}

struct FirmDecoder : EntityDecoder {
  func decode<Firm>(json: [String : AnyObject], index: Int) -> Firm {
    return Firm()
  }
}

//extension EntityDecoder {
// func decode<Firm>(json: [String : AnyObject], index: Int) -> Firm {
// return Firm()
// }
//}

http://i.stack.imgur.com/q6bAE.png

提前致谢。

更新 @JeremyP @mixel我并不是要将FirmDecoder.decode()声明为通用函数。那么你的原始答案&#34;是我想要实现的目标。

我是否正确地认为,不必为FirmDecoder实现.decode,我可以制作扩展协议来提供默认实现,因此FirmDecoder只需要实现您在更新后的答案中提出的HasInitializer。

类似的东西(我目前无法访问XCode):

protocol HasJsonInitializer {
    init(json: [String:AnyObject], index: Int)
}

protocol EntityDecoder {
    func decode<U: HasJsonInitializer>(json: [String:AnyObject], index: Int) -> U
}

extension EntityDecoder {
    func decode<U: HasJsonInitializer>(json: [String : AnyObject], index: Int) -> U {
        return U(json, index: index)
    }
}

struct FirmDecoder : EntityDecoder, HasJsonInitializer {
    init(json: [String:AnyObject], index: Int) {
        // json processing
    }
}

感谢您的投入。

1 个答案:

答案 0 :(得分:1)

<强>更新

如果你想保留decode<U>作为通用函数,那么你应该向泛型参数U添加一个约束,该约束表明U必须有没有参数的初始值设定项:

protocol HasInitializer {
    init()
}

protocol EntityDecoder {
    func decode<U: HasInitializer>(json: [String:AnyObject], index: Int) -> U
}

struct FirmDecoder : EntityDecoder {
    func decode<Firm: HasInitializer>(json: [String : AnyObject], index: Int) -> Firm {
        return Firm()
    }
}

并且不要对通用参数和结构使用相同的名称Firm。这令人困惑。

原始回答

EntityDecoderFirmDecoder定义无效,这是正确的方式:

import UIKit
protocol EntityDecoder {
    typealias U
    func decode(json: [String:AnyObject], index: Int) -> U
}

public struct Firm {
    public init() {}
}

struct FirmDecoder : EntityDecoder {
    func decode(json: [String : AnyObject], index: Int) -> Firm {
        return Firm()
    }
}