gpt4 book ai didi

swift - 在 Swift 3 中使用 SWXMLHash 反序列化一个类

转载 作者:行者123 更新时间:2023-11-28 11:02:42 24 4
gpt4 key购买 nike

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

method 'deserialize' in non-final class 'Element' must return Self to conform to protocol '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
}

}

最佳答案

反序列化实现没有实现蓝图

您自己的 deserialize 函数没有实现 XMLElementDeserializable 的蓝图,这意味着 deserialize 的默认实现(来自 XMLElementDeserializable) 将对您的类 Element 可用。这个默认实现是一个抛出错误的实现,这是你有点混淆的错误消息的来源。

来自 the source code of the SWXMLHash framework

/// 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!

这会产生以下错误消息:

error: method 'bar' in non-final class 'Bar' must return Self to conform to protocol '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 实例),将 Bar 标记为 final 并显式注释 self

的类型
/* ... FooError and Foo as above */

final class Bar : Foo {
static func bar(_ baz: Int) throws -> Bar {
return Bar()
}
}

应用于您的用例

考虑到以上情况,你需要修改你的反序列化签名为

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 实现没有多大意义,因为它没有使用要反序列化的对象(内部参数名称 element),但既然你提到你的例子被精简了,我会假设这是为了这个例子。

关于swift - 在 Swift 3 中使用 SWXMLHash 反序列化一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39953031/

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