gpt4 book ai didi

Swift 在泛型和协议(protocol)中使用 Self(在方法级别没有初始化)

转载 作者:行者123 更新时间:2023-11-28 06:24:07 24 4
gpt4 key购买 nike

更新:该问题投票决定将此作为与 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()
}
}

这是行不通的。这些都不起作用:

  1. 回归故事
  2. Story() 转换为!自己

查看更新的 Playground gist .

最佳答案

class Story : IParse {
required init()
{
}

public static func parse(json: String) -> Self
{
return self.init()
}
}

这会起作用。这确保您实际构建了一个 Self 的实例,这样 StoryTale 子类就不会创建一个无聊的 Story,但确实是一个美妙的故事。

required 关键字强制子类覆盖此 init,因此我们确信在解析中实际调用 self.init() 是有效的。


另一个解决方案,如果你不想与继承斗争,那就是让 Storyfinal

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com