可选值上的 KeyPath 出现奇怪错误

Posted

技术标签:

【中文标题】可选值上的 KeyPath 出现奇怪错误【英文标题】:Strange error with KeyPath on optional value 【发布时间】:2019-07-22 07:38:00 【问题描述】:

考虑下面的sn-p代码

class A 
    
    var value: Int?
    


let a: A? = A()
let kp = \A.value
a?[keyPath: kp] = 10
print(a?.value)

这很完美,Optional(10) 会按预期打印。在我的实际应用程序中,我试图以这种方式设置的字段被声明为Date?,它会导致一些奇怪的错误。我实际应用的 MWE 是这样的:

class A 
    
    var value: Date?
    


let a: A! = A()
let kp = \A.value
a?[keyPath: kp] = Date() // Line with error
print(a?.value)

但是编译器抱怨突出显示的行并说:

可选类型“日期?”的值必须解包为“日期”类型的值

修复:使用 '??' 合并当可选值包含'nil'时提供默认值

修复:使用“!”强制解包如果可选值包含'nil'则中止执行

这是编译器的一个错误,我们可以期望在最终版本之前修复,还是我对键路径不了解?

我使用的是 Xcode 11 beta 3,但我在 beta 2 中也遇到了同样的问题。如果有用,实际代码是 here。

【问题讨论】:

这是一个错误,已提交报告:bugs.swift.org/browse/SR-11184 【参考方案1】:

不带 !和 ?作品

let a = A()
let kp = \A.value
a[keyPath: kp] = Date() 
print(a.value)

或仅作为可选

let a: A? = A()
let kp = \A.value
a?[keyPath: kp] = Date() 
print(a?.value)

【讨论】:

奇怪的东西。由于使用正常的可选它可以工作,我猜这是编译器的错误 @Joakim 不能使用强制可选的原因是什么? @PGDev,我无法真正解释这一点,因为我不完全理解在这种情况下键路径如何与选项一起使用。【参考方案2】:

我遇到了类似的问题:

import Foundation

struct Outer 
    var inner: Inner

    init() 
        inner = Inner()
    


struct Inner 
    var date: Date?


var outer = Outer()
outer[keyPath: \Outer.inner][keyPath: \Inner.date] = Date() // Line with error
print(outer.inner.date)
error: value of optional type 'Date?' must be unwrapped to a value of type 'Date'
outer[keyPath: \Outer.inner][keyPath: \Inner.date] = Date() // Line with error
                            ^
note: coalesce using '??' to provide a default when the optional value contains 'nil'
outer[keyPath: \Outer.inner][keyPath: \Inner.date] = Date() // Line with error
                            ^
                                                   ?? <#default value#>
note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
outer[keyPath: \Outer.inner][keyPath: \Inner.date] = Date() // Line with error
                            ^
                                                  !

奇怪的是,将值转换为可选的作品

outer[keyPath: \Outer.inner][keyPath: \Inner.date] = Date() as Date? // Works

因此,我认为解决此问题的更通用的方法是将值显式转换为可选的as Date?

【讨论】:

以上是关于可选值上的 KeyPath 出现奇怪错误的主要内容,如果未能解决你的问题,请参考以下文章

不断出现致命错误:在展开可选值时意外发现 nil

NSEntityDescription 在展开可选值时返回 nil

SLD2:使用 SDL2_gfx 和 AntTweakBar 在 OS X 上出现奇怪的渲染错误

ActivityIndi​​cator(微调器)出现错误在展开可选值时意外发现 nil

发现可选值错误 nil swift 3

Codeigniter 日志中出现奇怪的 404 错误