gpt4 book ai didi

swift - iOS 12 SDK 通用函数返回 Optional.some(nil)

转载 作者:搜寻专家 更新时间:2023-10-31 08:28:19 25 4
gpt4 key购买 nike

使用 Xcode 10,但没有迁移到 Swift 4.2,所以我的项目仍在使用 Swift 4.1 运行。

假设我在 Dictionary 上有以下扩展:

extension Dictionary where Key: ExpressibleByStringLiteral {
func find<T>(key: Key) -> T? {
return self[key] as? T
}
}

我使用此函数以类型安全的方式访问 hashmap 中的值,例如:

 let dict: [String: Any] = ["foo": "bar"]
let foo: String? = dict.find(key: "foo") // prints "bar"

当我希望从我的 find 函数返回 Any 类型时,我的问题浮出水面,例如:

 let bar: Any? = dict.find(key: "bar")

Xcode 10 之前,如果在散列映射中找不到键,这个函数过去常常向我返回简单明了的 nil

但是,在 Xcode 10 之后,它返回 Optional.some(nil)

我明白,任何类型都可以像下面这样初始化:

let foo: Any = Optional<String>.none

我想在我的情况下也会发生类似的事情。有没有人知道如何解决它并仍然从 find 函数返回 nil

最佳答案

这是由于有意更改 (#13910),编译器现在更保守地解包一个被转换为通用占位符类型的可选值。现在,您获得的结果与您在非通用上下文中获得的结果更加一致(有关进一步讨论,请参阅 SR-8704)。

例如:

// note the constraint `where Key : ExpressibleByStringLiteral` is needlessly restrictive.
extension Dictionary where Key : ExpressibleByStringLiteral {
func find<T>(key: Key) -> T? {
return self[key] as? T
}
}

let dict: [String: Any] = ["foo": "bar"]

let genericBar: Any? = dict.find(key: "bar")
print(genericBar as Any) // in Swift 4.1: nil, in Swift 4.2: Optional(nil)

// `T` in the above example is inferred to be `Any`.
// Let's therefore substitute `as? T` with `as? Any`.
let nonGenericBar = dict["bar"] as? Any
print(nonGenericBar as Any) // in both versions: Optional(nil)

如您所见,无论是否使用通用占位符来执行转换,您现在都会得到 Optional(nil),从而使行为更加一致。

为什么您最终得到 Optional(nil) 的原因是因为您正在执行有条件地转换可选值。条件转换本身会产生一个可选值以指示成功或失败,并将生成的可选值放入成功案例中会为您提供双重包装的可选值。并且由于您正在转换为 Any,它可以表示 Optional 值,因此不需要进行解包以“适合”结果类型中的值。

如果您希望将生成的可选项展平为单独包装的可选项,您可以合并 nil:

extension Dictionary {
func find<T>(key: Key) -> T? {
return (self[key] as? T?) ?? nil
}
}

或者在转换之前解包值,例如使用guard:

extension Dictionary {
func find<T>(key: Key) -> T? {
guard let value = self[key] else { return nil }
return value as? T
}
}

或者,我的首选方法是使用 flatMap(_:) :

extension Dictionary {
func find<T>(key: Key) -> T? {
return self[key].flatMap { $0 as? T }
}
}

综上所述,我经常发现 [String: Any] 的用法是一种代码味道,强烈表明应该使用更强大的类型。除非键真的可以是任意字符串(而不是一组固定的静态已知键),并且值真的可以是特定键的任何类型——几乎当然,您可以使用更好的类型来对数据建模。

关于swift - iOS 12 SDK 通用函数返回 Optional.some(nil),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52446097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com