[英]Deserialising a class with SWXMLHash in Swift 3
我正在嘗試使用自述文件末尾提供的示例將XML反序列化為一個類,但是它引發了與最初引發此問題相同的編譯時錯誤。
非最終類“元素”中的方法“反序列化”必須返回
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
}
}
deserialize
實現未實現藍圖 您自己的deserialize
函數無法實現XMLElementDeserializable
藍圖,這意味着deserialize
的默認實現(來自XMLElementDeserializable
)將對您的類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
實例),請將Bar標記為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
實現沒有多大意義,因為它沒有利用要反序列化的對象(內部參數name element
),但是由於您提到了示例,因此我假設這是有意的例如)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.