我正在尝试从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中的类型推断错误,还是我遗漏了一些非常明显的错误
答案 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