Swift 泛型、结构和协议:没有可访问的初始化器

Swift Generics, Stucts and Protocol: No accessible initializers

为什么这段代码不能编译?

编译错误在 struct FirmDecoder "return Firm()".

错误消息是:'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() 声明为通用函数。所以你的 "orginal answer" 就是我想要达到的目标。

我的想法是否正确,不必为 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
    }
}

感谢您的意见。

更新

如果您想将 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()
    }
}