swift 字典值采用方法类型而不是属性类型

gblwokeq  于 2023-03-07  发布在  Swift
关注(0)|答案(1)|浏览(115)

我有一个字典,可以有StringInt值,我用compactMapValues删除了nil值。
其中一个字符串值为capitalized
总而言之,我的代码如下所示:

let someOptional: Int? = nil

let test: [AnyHashable: Any] = [
    "Some optional" : someOptional,
    "Some capitalized string" : "\(true)".capitalized
].compactMapValues { $0 }

当我访问第二个值时:

test["Some capitalized string"]!

我得到这个:(Function),而不是True
我猜这是因为capitalized也是一个方法,Dictionary可能采用方法类型而不是var类型。
但是为什么呢?我怎么才能强迫它接受var而不是func呢?
我找到的唯一解决方案是在capitalized之后添加as String,但我发现需要这样做很奇怪。
另外奇怪的是,如果我从列表中删除可选条目,它就能工作。或者如果我用"true"替换"\(true)",它也能工作。

rjjhvcjd

rjjhvcjd1#

您可以(但不应该)使用KeyPath下标执行此操作:

"Some capitalized string" : "\(true)"[keyPath: \.capitalized]

这样就避免了将属性本身视为函数的可能性。有了它,完整的Any解决方案看起来就像这样:

let test: [AnyHashable: Any] = [
    "Some optional" : someOptional as Any,
    "Some capitalized string" : "\(true)"[keyPath: \.capitalized]
].compactMapValues { (value) -> Any? in
    switch value {
    case let int as Int?: return int
    default: return value
    }
}

复杂的compactMapValues是必需的,因为当前的compactMapValues实际上没有做任何事情:

print(test)
[AnyHashable("Some capitalized string"): (Function), 
 AnyHashable("Some optional"): nil]

注意“Some optional”在Dictionary中的实际情况吗?它并没有像您所期望的那样被过滤掉,因为它的值是.some(nil)。(如果您感兴趣的话,问题在于可选的升级和Any?的递归特性)。(表达式从“Int?”隐式强制为“Any'),这就是为什么需要as Any,即使可以通过这种笨拙的方式避免as String
奇怪的是,你试图在这里使用Any作为你的类型。这总是会导致笨拙的类型解析。当你试图把Optional放在字典里时,就更笨拙了。
如果类型是String或Int,则使用枚举。
对于有条件地插入内容,我的建议是保持简单,只需if-let即可:

import Foundation

enum YourValue {
    // Use names here that match the meaning of these values.
    // "string" and "int" are here because you didn't tell us
    // what the values mean.
    case string(String)
    case int(Int)
}

let someOptional: Int? = nil

var test: [String: YourValue] = [
    "Some capitalized string" : .string("\(true != false)".capitalized)
]
if let someOptional {
    test["SomeOptional"] = .int(someOptional)
}

或者,如果compactMapValues确实对您有帮助,您仍然可以使用它:

let test: [String: YourValue] = [
    "Some capitalized string" : .string("\(true != false)".capitalized),
    "SomeOptional": someOptional.map(YourValue.int)
].compactMapValues { $0 }

不要用任何药物,你会不断地抵抗它。

相关问题