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

在Swift 3中使用SWXMLHash反序列化类,swift,swift3,swxmlhash,Swift,Swift3,Swxmlhash,我试图使用自述文件末尾提供的示例将XML反序列化到一个类,但它引发了与最初引发的编译时错误相同的编译时错误 非最终类“Element”中的方法“反序列化”必须返回Self,以符合协议“XMLElementDeserializable” 我已经尝试尽可能逐字地使用这个示例(尽管随着Date结构的改变,现在主要在NSDate中使用),但我仍然遇到同样的问题 这就是我正在尝试使用的代码(本质上完全相同,只是为了清晰起见而简化了) import Foundation import SWXMLHash

我试图使用自述文件末尾提供的示例将XML反序列化到一个类,但它引发了与最初引发的编译时错误相同的编译时错误

非最终类“Element”中的方法“反序列化”必须返回
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我来帮忙!