首页 > 解决方案 > 使用 Dictionary(uniqueKeysWithValues:) 在 Swift 5 中转换字典键类型

问题描述

我正在使用 Alamofire 5 为 iOS 13.4(Swift 5,Xcode 11)编写一个具有网络功能的应用程序。我创建了我的自定义类型typealias KeyedParameters = [ParameterKeys: Any],以便能够以“swifty”的快捷方式(即.login,而不是KeyedParameters.login.rawValue)使用我的 API 参数键。

问题是当我尝试将此类型转换回默认 Alamofire'sParameters时,我收到以下错误:Cannot convert return expression of type 'Dictionary<ParameterKeys, Any>' to return type 'Parameters' (aka 'Dictionary<String, Any>').

铸件:

extension KeyedParameters {
    var parameters: Parameters {
        Dictionary(uniqueKeysWithValues: map { ($0.key.rawValue, $0.value) })
    }
}

参数键:

enum ParameterKeys: String {
    // MARK: - Auth and User
    case id, login, password, email, name
    case createdAt = "created_at"
    ...
}

错误的外观:

在此处输入图像描述

标签: iosswiftxcodealamofireswift5

解决方案


我认为这可能只是错误消息错误的情况。

您的扩展名KeyedParameters(a typealiasfor [ParameterKeys: Any])实际上等同于:

extension Dictionary where Key == ParameterKeys, Value: Any { ...

在泛型类型的声明中调用该类型的初始化器时,Swift 有一些奇怪的行为。如果泛型类型不同,它将无法正确处理。

这是一个更简单的示例,没有太多的红鲱鱼(类型别名、枚举原始值等)和依赖项:

extension Dictionary  {
    func returnADifferentDict() -> [Character: String] {
        let words = [
            "apple", "anchovies",
            "bacon", "beer",
            "celery"
        ]

        return Dictionary(uniqueKeysWithValues:
            words.map { ($0.first!, $0) }
        )

//      fixed:
//      return Dictionary<Character, String>(uniqueKeysWithValues:
//          words.map { ($0.first!, $0) }
//      )

    }
}

解决方案是显式指定您正在初始化的泛型类型的泛型类型参数。在你的情况下,

extension KeyedParameters {
    var parameters: Parameters {
        Dictionary<String, Any>(uniqueKeysWithValues: map { ($0.key.rawValue, $0.value) })
    }
}

推荐阅读