在Swift 3中使用SWXMLHash反序列化类
我试图使用自述文件末尾提供的示例将XML反序列化到一个类,但它引发了与最初引发的编译时错误相同的编译时错误 非最终类“Element”中的方法“反序列化”必须返回在Swift 3中使用SWXMLHash反序列化类,swift,swift3,swxmlhash,Swift,Swift3,Swxmlhash,我试图使用自述文件末尾提供的示例将XML反序列化到一个类,但它引发了与最初引发的编译时错误相同的编译时错误 非最终类“Element”中的方法“反序列化”必须返回Self,以符合协议“XMLElementDeserializable” 我已经尝试尽可能逐字地使用这个示例(尽管随着Date结构的改变,现在主要在NSDate中使用),但我仍然遇到同样的问题 这就是我正在尝试使用的代码(本质上完全相同,只是为了清晰起见而简化了) import Foundation import SWXMLHash
Self
,以符合协议“XMLElementDeserializable”
我已经尝试尽可能逐字地使用这个示例(尽管随着Date结构的改变,现在主要在NSDate中使用),但我仍然遇到同样的问题
这就是我正在尝试使用的代码(本质上完全相同,只是为了清晰起见而简化了)
import Foundation
import SWXMLHash
class Element: XMLElementDeserializable {
public static func deserialize(element: SWXMLHash.XMLElement) throws -> Self {
return value(Element())
}
private static func value<T>(_ element: Element) -> T {
return element as! T
}
}
<代码>导入基础
导入SWXMLHash
类元素:XMLElementDeserializable{
公共静态func反序列化(元素:SWXMLHash.xmlement)抛出->Self{
返回值(元素())
}
私有静态func值(u元素:元素)->T{
返回元素为!T
}
}
反序列化
实现不实现蓝图中的实现
您自己的反序列化
函数没有实现从xmlementdeserializable
蓝图打印的函数,这意味着反序列化
的默认实现(从xmlementdeserializable
)将对类元素
可用。此默认实现是一个抛出错误的实现,这是您的一些模糊错误消息的来源
enum FooError : Error {
case error
}
protocol Foo {
static func bar(_ baz: Int) throws -> Self
}
extension Foo {
static func bar(_ baz: Int) throws -> Self {
throw FooError.error
}
}
// Bar implements its own bar(baz:) method, one which does
// NOT implement bar(_:) from the protocol Foo. This means
// that the throwing erroneous default implementation of
// bar(_:) becomes available to Bar, yielding the same error
// message as in your question
class Bar : Foo {
// does not match the blueprint!
static func bar(baz: Int) throws -> Self {
return value(Bar())
}
private static func value<T>(_ bar: Bar) -> T {
return bar as! T
}
}
// Error!
从
请注意,反序列化
方法的签名与蓝图方法的签名不匹配:后者显式地省略了其外部参数名(
),而您的方法没有
用最少的例子分析错误案例
我们可以构造一个类似的最小示例来获得相同的错误消息
enum FooError : Error {
case error
}
protocol Foo {
static func bar(_ baz: Int) throws -> Self
}
extension Foo {
static func bar(_ baz: Int) throws -> Self {
throw FooError.error
}
}
// Bar implements its own bar(baz:) method, one which does
// NOT implement bar(_:) from the protocol Foo. This means
// that the throwing erroneous default implementation of
// bar(_:) becomes available to Bar, yielding the same error
// message as in your question
class Bar : Foo {
// does not match the blueprint!
static func bar(baz: Int) throws -> Self {
return value(Bar())
}
private static func value<T>(_ bar: Bar) -> T {
return bar as! T
}
}
// Error!
如果我们在bar
中修复bar
方法的签名,使之与Foo
中蓝图中的签名相匹配,我们将不再收到错误提示
/* ... FooError and Foo as above */
// Bar implements bar(_:) from protocol Foo, which
// means the throwing erroneous default implementation
// of bar(_:) is never in effect, OK
class Bar : Foo {
static func bar(_ baz: Int) throws -> Self {
return value(Bar())
}
private static func value<T>(_ bar: Bar) -> T {
return bar as! T
}
}
应用于您的用例
考虑到上述因素,您需要将签名反序列化为
public static func deserialize(_ element: SWXMLHash.XMLElement) throws -> Self { /* ... */ }
或者,如果您不打算对元素
类本身进行子类化,则将其标记为final
,允许注释具体的返回类型元素
,而不是Self
:
final class Element: XMLElementDeserializable {
public static func deserialize(_ element: SWXMLHash.XMLElement) throws -> Element { /* ... */ }
}
(请注意,反序列化
的当前实现没有多大意义,因为它没有使用要反序列化的对象(内部参数名称元素
),但由于您提到您的示例已被剥离,我假定这是用于示例的)
您自己的反序列化
函数没有实现从xmlementdeserializable
蓝图打印的函数,这意味着反序列化
的默认实现(从xmlementdeserializable
)将对类元素
可用。此默认实现是一个抛出错误的实现,这是您的一些模糊错误消息的来源
enum FooError : Error {
case error
}
protocol Foo {
static func bar(_ baz: Int) throws -> Self
}
extension Foo {
static func bar(_ baz: Int) throws -> Self {
throw FooError.error
}
}
// Bar implements its own bar(baz:) method, one which does
// NOT implement bar(_:) from the protocol Foo. This means
// that the throwing erroneous default implementation of
// bar(_:) becomes available to Bar, yielding the same error
// message as in your question
class Bar : Foo {
// does not match the blueprint!
static func bar(baz: Int) throws -> Self {
return value(Bar())
}
private static func value<T>(_ bar: Bar) -> T {
return bar as! T
}
}
// Error!
从
请注意,反序列化
方法的签名与蓝图方法的签名不匹配:后者显式地省略了其外部参数名(
),而您的方法没有
用最少的例子分析错误案例
我们可以构造一个类似的最小示例来获得相同的错误消息
enum FooError : Error {
case error
}
protocol Foo {
static func bar(_ baz: Int) throws -> Self
}
extension Foo {
static func bar(_ baz: Int) throws -> Self {
throw FooError.error
}
}
// Bar implements its own bar(baz:) method, one which does
// NOT implement bar(_:) from the protocol Foo. This means
// that the throwing erroneous default implementation of
// bar(_:) becomes available to Bar, yielding the same error
// message as in your question
class Bar : Foo {
// does not match the blueprint!
static func bar(baz: Int) throws -> Self {
return value(Bar())
}
private static func value<T>(_ bar: Bar) -> T {
return bar as! T
}
}
// Error!
如果我们在bar
中修复bar
方法的签名,使之与Foo
中蓝图中的签名相匹配,我们将不再收到错误提示
/* ... FooError and Foo as above */
// Bar implements bar(_:) from protocol Foo, which
// means the throwing erroneous default implementation
// of bar(_:) is never in effect, OK
class Bar : Foo {
static func bar(_ baz: Int) throws -> Self {
return value(Bar())
}
private static func value<T>(_ bar: Bar) -> T {
return bar as! T
}
}
应用于您的用例
考虑到上述因素,您需要将签名反序列化为
public static func deserialize(_ element: SWXMLHash.XMLElement) throws -> Self { /* ... */ }
或者,如果您不打算对元素
类本身进行子类化,则将其标记为final
,允许注释具体的返回类型元素
,而不是Self
:
final class Element: XMLElementDeserializable {
public static func deserialize(_ element: SWXMLHash.XMLElement) throws -> Element { /* ... */ }
}
(请注意,反序列化
的当前实现没有多大意义,因为它没有使用要反序列化的对象(内部参数名称元素
),但由于您提到您的示例已被剥离,我假定这是用于示例的).这是正确的。另外,仅供参考@Oliver Cooper,我的文档已经过时。对于版本2,该响应是正确的,但对于Swift 3.0,实现API也有轻微更改。我将更新相关的StackOverflow答案。一个非常棒、详细的答案!非常感谢,我很惊讶它如此微妙。@Oliver Cooper高兴帮助!这是正确的。另外,仅供参考@Oliver Cooper,我的文档已经过时。对于版本2,该响应是正确的,但对于Swift 3.0,实现API也有轻微更改。我将更新相关的StackOverflow答案。一个奇妙的、详细的答案!非常感谢,我很惊讶这是如此微妙的事情。@Oliver Cooper hap我来帮忙!