簡體   English   中英

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

[英]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可用。 此默認實現是拋出錯誤的實現,這是造成您混淆不清的錯誤消息的來源。

SWXMLHash框架的源代碼

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM