更新:
该问题投票决定将此作为与 self.init()
的重复交易关闭,这可以通过将类标记为 final 或需要 init 来解决。但是这如何在存储库上工作或从 init
以外的任何其他方法返回(我的实现是 @NSManaged 对象)
这是我想做的。通过请求获取 JSON,然后将其解析为对象。
var req = Request("http://somewhere/story/get/1")
var story = req.parseJsonResponse() as Story
Request
类看起来像这样:
class Request {
public var httpJsonResponse : String
init(_ url : String) {
//This comes from HTTP
httpJsonResponse = "{}"
}
public func parseJsonResponse<T : IParse>() -> T {
return T.parse(json: httpJsonResponse)
}
}
现在,我想确保 IParse
实现有解析方法:
protocol IParse {
static func parse(json : String) -> Self
}
到目前为止一切顺利,这是实现方面的问题:
class Story : IParse {
required init()
{
}
public static func parse(json: String) -> Self
{
//return self.init() works thanks to @tomahh
return StoryRepo.ById(1)
}
}
class StoryRepo {
public static func ById(_ id : Int) -> Story {
return Story()
}
}
这是行不通的。这些都不起作用:
- 回归故事
- 将
Story() 转换为!自己
查看更新的 Playground gist .
最佳答案
class Story : IParse {
required init()
{
}
public static func parse(json: String) -> Self
{
return self.init()
}
}
这会起作用。这确保您实际构建了一个 Self
的实例,这样 Story
的 Tale
子类就不会创建一个无聊的 Story
,但确实是一个美妙的故事。
required
关键字强制子类覆盖此 init,因此我们确信在解析中实际调用 self.init()
是有效的。
另一个解决方案,如果你不想与继承斗争,那就是让 Story
类 final
final Story: IParse {
public static func parse(json: String) -> Story {
return Story()
}
}
在这个例子中,因为 Story
永远不会被继承,所以调用 Story()
并返回一个 Story
类型是安全的parse
函数。
关于Swift 在泛型和协议(protocol)中使用 Self(在方法级别没有初始化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42498699/