gpt4 book ai didi

具有泛型类型的 Swift 协议(protocol)

转载 作者:可可西里 更新时间:2023-11-01 02:14:08 26 4
gpt4 key购买 nike

我正在尝试创建一个具有返回泛型类型的静态方法的协议(protocol)。在大多数情况下,我所拥有的似乎工作得相当好。当我想使用扩展来返回这个通用值时,挑战就来了。这就是我所拥有的。可以将此代码放入 Playground 。

这是我想要的第一个协议(protocol),它包含 associatedtype

protocol AWSerializable {
associatedtype T

static func deserialize(dictionary: [String : Any]) -> T?
func serialize() -> [String : Any]
}

然后我创建了另一个协议(protocol),它允许我创建执行反序列化操作的实例:

protocol AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T?
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]?
}

这是一个成功实现 AWSerializable 协议(protocol)的示例:

class FooBar: AWSerializable {

typealias T = FooBar

var foo = ""
var bar = ""

static func deserialize(dictionary: [String : Any]) -> FooBar? {
let fooBar = FooBar()

fooBar.foo = (dictionary["foo"] as? String) ?? ""
fooBar.bar = (dictionary["bar"] as? String) ?? ""

return fooBar
}

func serialize() -> [String : Any] {
var serialized = [String : Any]()

serialized["foo"] = foo
serialized["bar"] = bar

return serialized
}

}

到目前为止一切顺利。当我想在 UserDefaults 上创建一个 extension 以实现 AWDeserializer 协议(protocol)时,挑战就来了。

extension UserDefaults: AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T? {
if let serialized = UserDefaults.standard.object(forKey: key) as? [String : Any] {
return T.deserialize(dictionary: serialized)
}

return nil
}

func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]? {
if let data = UserDefaults.standard.array(forKey: key) as? [[String : Any]] {
var values = [T]()

for entry in data {
if let value = T.deserialize(dictionary: entry) {
values.append(value)
}
}

return values
}

return nil
}
}

这里的问题是 T.deserialize(dictionary: serialized)。我收到以下错误:

enter image description here

这可以通过应用建议的解决方案轻松解决,或者最好将行更改为 return T.deserialize(dictionary: serialized) as? T

但我不喜欢这样一个事实,即这个可选的转换是必需的。有没有一种方法可以定义不需要此转换的协议(protocol)?

最佳答案

也许使用这个协议(protocol)AWDeserializer会好得多:

protocol AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T? where T.T == T
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]? where T.T == T
}

代替:

protocol AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T?
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]?
}

下面是剩余的代码:

protocol AWSerializable {
associatedtype T

static func deserialize(dictionary: [String : Any]) -> T?
func serialize() -> [String : Any]
}

protocol AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T? where T.T == T
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]? where T.T == T
}

class FooBar: AWSerializable {

typealias T = FooBar

var foo = ""
var bar = ""

static func deserialize(dictionary: [String : Any]) -> FooBar? {
let fooBar = FooBar()

fooBar.foo = (dictionary["foo"] as? String) ?? ""
fooBar.bar = (dictionary["bar"] as? String) ?? ""

return fooBar
}

func serialize() -> [String : Any] {
var serialized = [String : Any]()

serialized["foo"] = foo
serialized["bar"] = bar

return serialized
}

}

extension UserDefaults: AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T? where T.T == T {
if let serialized = UserDefaults.standard.object(forKey: key) as? [String : Any] {
return T.deserialize(dictionary: serialized)
}

return nil
}

func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]? where T.T == T {
if let data = UserDefaults.standard.array(forKey: key) as? [[String : Any]] {
var values = [T]()

for entry in data {
if let value = T.deserialize(dictionary: entry) {
values.append(value)
}
}

return values
}

return nil
}
}

关于具有泛型类型的 Swift 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39772537/

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