在Swift 3中使用SWXMLHash对类进行反序列化

时间:2016-10-10 07:17:29

标签: swift swift3 swxmlhash

我正在尝试使用自述文件末尾提供的示例将XML反序列化为类,但它引发的编译时错误与最初激发的this question相同。

  

非终结类'Element'中的方法'deserialize'必须返回Self以符合协议'XMLElementDeserializable'

我试图尽可能逐字地使用这个例子(尽管改变了很多,因为Date,一个struct,现在主要用于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
    }

}

1 个答案:

答案 0 :(得分:3)

deserialize实现没有实现blueprinted

的实现

您自己的deserialize函数未实现XMLElementDeserializable中的蓝色版本,这意味着deserialize(来自XMLElementDeserializable)的默认实现将可用于您的班级{{ 1}}。这个默认实现是抛出错误的实现,这是你有点混淆的错误消息的来源。

来自the source code of the SWXMLHash framework

Element

请注意/// Provides XMLElement deserialization / type transformation support public protocol XMLElementDeserializable { /// Method for deserializing elements from XMLElement static func deserialize(_ element: XMLElement) throws -> Self /* ^^^^^^^^^- take note of the omitted external name in this signature */ } /// Provides XMLElement deserialization / type transformation support public extension XMLElementDeserializable { /** A default implementation that will throw an error if it is called - parameters: - element: the XMLElement to be deserialized - throws: an XMLDeserializationError.ImplementationIsMissing if no implementation is found - returns: this won't ever return because of the error being thrown */ static func deserialize(_ element: XMLElement) throws -> Self { throw XMLDeserializationError.ImplementationIsMissing( method: "XMLElementDeserializable.deserialize(element: XMLElement)") } } 方法的签名与蓝图方法的签名不匹配:后者明确省略了其外部参数名称(deserialize),而您的方法则没有。

使用最小示例分析错误案例

我们可以构造一个类似的,最小的例子来实现相同的错误信息。

_

产生以下错误消息:

  

错误:非最终班级“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   符合协议“Self

Foo

如果我们在 static func bar(_ baz: Int) throws -> Self { ... 中修复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 } } 推断为有效Bar()实例),请将栏标记为Self并明确注释final的类型

Self

适用于您的用例

考虑到上述情况,您需要将/* ... FooError and Foo as above */ final class Bar : Foo { static func bar(_ baz: Int) throws -> Bar { return Bar() } } 签名修改为

deserialize

或者,如果您不打算继承public static func deserialize(_ element: SWXMLHash.XMLElement) throws -> Self { /* ... */ } 类本身的子类,请将其标记为Element,以允许注释具体的返回类型final而不是Element

Self

(请注意,您当前的final class Element: XMLElementDeserializable { public static func deserialize(_ element: SWXMLHash.XMLElement) throws -> Element { /* ... */ } } 实现没有多大意义,因为它没有使用要反序列化的对象(内部参数名deserialized),但是因为你提到你的例子被剥离了,我认为这是用于示例的。)