如何为特定类型的字典定义扩展名?

时间:2018-10-05 07:37:11

标签: ios swift

我已经创建了typealias

typealias Multilang = [String: Any]

现在,我想使用属性localized扩展该Dictionary。有可能吗?

我需要如何使用它?

let dictionary: Multilang = ["en": "b", "pl": "d"]()
let value = dictionary.localized

我尝试这样做:

extension Dictionary where Dictionary: Multilang {
    var localized: String {
        print("self: \(self)")
        return "hello"
   }
}

但是它不起作用。为什么?

Type 'Dictionary(Key, Value)' constrained to non-protocol, non-class type 'Multilang' (aka 'Dictionary(String, Any)')

3 个答案:

答案 0 :(得分:2)

您可以编写这样的扩展名:

extension Dictionary where Dictionary == Multilang

或:

... The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Could not get JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory Communications link failure ...

答案 1 :(得分:2)

(不幸的)无法以这种方式使用typealias,因为它不会创建新的类型。例如,您可以使用typealias Foo = [String: Any]typealias Bar = [String: Any],但是FooBar仍然是同一类型。

因此,要么必须扩展所有[String: Any]字典,要么需要创建包装类型(您也不能继承Dictionary的子类,因为它是struct)。例如:

struct Multilang<Element> {
    var dictionary: [String: Element]
    var localized: Element? {
        return dictionary[currentLanguage]
    }
}

缺点是,您需要通过multilang.foo语法定义要使用的所有包装方法和属性,但是如果只需要multilang.localized,则可以通过{ {1}}。

您还可以实现multilang.dictionary.foo以使创建这些对象变得容易:

ExpressibleByDictionaryLiteral

答案 2 :(得分:1)

对于Swift 3及更高版本,您可以尝试使用此方法来扩展[String: Any]类型的字典。

extension Dictionary where Key: ExpressibleByStringLiteral, Value: Any {
    // Your extension code
    var localized: String {
    print("self: \(self)")
    return "hello"
}

ExpressibleByStringLiteralStringStaticString类型符合的协议。

您不能仅将其应用于类型别名,因为Multilang只是[String:Any]的标签,因此即使您可以扩展它,它也将始终扩展该类型的所有字典。