Swift Impossible Type推理

时间:2016-12-21 04:17:12

标签: swift swift3 nsurl type-inference

我正在尝试从Swift 3中的应用程序包中加载一个文件,我遇到了Swift类型推理的奇怪情况。如果我使用以下代码,我会在第三行显示错误Value of optional type "String?" not unwrapped

let url = NSURL(fileURLWithPath:Bundle.main.bundlePath)
let url2 = url.appendingPathComponent("foo.txt")
let path:String = url2?.path

要解决错误,我将第三行的值解包为:

let path:String = url2?.path!

我现在收到错误Cannot force unwrap value of a non-optional type 'String'。似乎Swift无法确定路径属性是String还是String?。 Xcode中的自动填充功能表示它是String,但文档称它是String?

Xcode针对第一个错误提出的修正建议是将url2?.path替换为(url2?.path)!,最终结果正常工作,但我不知道为什么会这样,其他方法则不然。< / p>

let path:String = (url2?.path)!

发生了什么事?这是Swift中的类型推断错误,还是我遗漏了一些非常明显的错误

3 个答案:

答案 0 :(得分:2)

在Swift中,可选链接如:

let path:String = url2?.path!

...被解释为:

let path:String = url2 != nil ? url2!.path!
                              : nil

如您所见,path的类型为非可选String,因此表达式会导致错误。

url2的类型为URL?,因此属性path的类型为String,而不是String?。)

这不是您问题的直接答案,但我会将您的代码重写为:

let url = Bundle.main.bundleURL
let url2 = url.appendingPathComponent("foo.txt")
let path:String = url2.path

更短,不用担心Optionals。

答案 1 :(得分:0)

您忘了打开url2

appendingPathComponent会返回一个可选值,您尝试访问它而不会将其解包。

所以,

let url2 = url.appendingPathComponent("foo.txt")!

guard let url2 = url.appendingPathComponent("foo.txt") else { }

应该解决它

修改

let path:String? = url2?.path

也有效

答案 2 :(得分:0)

你也可以这样做:

let url = Bundle.main.url(forResource: "foo", withExtension: "txt")!
let path:String = url.path