Swift 具有通用类型的协议
Swift protocol with generic types
我正在尝试创建一个协议,该协议具有 return 泛型类型的静态方法。在大多数情况下,我所拥有的似乎工作得相当好。当我想使用 return 这个通用值的扩展时,挑战就来了。这就是我所拥有的。此代码可以放入游乐场。
这是我想要的第一个协议,其中包含 associatedtype
protocol AWSerializable {
associatedtype T
static func deserialize(dictionary: [String : Any]) -> T?
func serialize() -> [String : Any]
}
然后我创建了另一个协议,允许我创建执行反序列化操作的实例:
protocol AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T?
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]?
}
这是一个成功实现 AWSerializable
协议的例子:
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
协议时,挑战就来了。
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)
。我收到以下错误:
这可以通过应用建议的解决方案轻松解决,或者最好将行更改为 return T.deserialize(dictionary: serialized) as? T
但我不喜欢这个可选的转换是必需的。有没有办法定义不需要此转换的协议?
也许使用这个协议会好很多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
}
}
我正在尝试创建一个协议,该协议具有 return 泛型类型的静态方法。在大多数情况下,我所拥有的似乎工作得相当好。当我想使用 return 这个通用值的扩展时,挑战就来了。这就是我所拥有的。此代码可以放入游乐场。
这是我想要的第一个协议,其中包含 associatedtype
protocol AWSerializable {
associatedtype T
static func deserialize(dictionary: [String : Any]) -> T?
func serialize() -> [String : Any]
}
然后我创建了另一个协议,允许我创建执行反序列化操作的实例:
protocol AWDeserializer {
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> T?
func deserializeWithKey<T: AWSerializable>(_ key: String!) -> [T]?
}
这是一个成功实现 AWSerializable
协议的例子:
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
协议时,挑战就来了。
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)
。我收到以下错误:
这可以通过应用建议的解决方案轻松解决,或者最好将行更改为 return T.deserialize(dictionary: serialized) as? T
但我不喜欢这个可选的转换是必需的。有没有办法定义不需要此转换的协议?
也许使用这个协议会好很多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
}
}