如果将文件加载到类中的字符串中出现问题,我希望Swift中的类 init()会抛出错误。加载文件后,字符串不会被更改,所以我更喜欢使用 let 。这有效:
class FileClass {
var text: NSString = ""
init() throws {
do {
text = try NSString( contentsOfFile: "/Users/me/file.txt", encoding: NSUTF8StringEncoding ) }
catch let error as NSError {
text = ""
throw error
}
}
}
但是当我替换
var text: NSString = ""
与
let text: NSString
我得到必须初始化类实例的所有存储属性,然后再从初始化程序错误中抛出。
我尝试了各种方法,例如使 text 可选
let text: NSString?
但没有找到任何工作。是否可以从文件中加载 text ,不可变,并且 init()会抛出错误?我可以吃蛋糕并吃三个吗?
非常感谢提前!
答案 0 :(得分:16)
从Swift 2.2开始,您可以打破类初始化程序的执行,而无需填充所有存储的属性
class FileStruct {
let text: String
init() throws {
do {
text = try String(contentsOfFile: "/Users/me/file.txt", encoding: NSUTF8StringEncoding ) }
catch let error as NSError {
throw error
}
}
}
目前在Swift class
中,您无法在初始化每个存储的属性之前中断初始化程序的执行。
另一方面,structs
所以
struct FileStruct {
var text: String
init() throws {
do {
text = try String(contentsOfFile: "/Users/me/file.txt", encoding: NSUTF8StringEncoding ) }
catch let error as NSError {
throw error
}
}
}
你也可以避免使用do / catch块
struct FileStruct {
var text: String
init() throws {
text = try String(contentsOfFile: "/Users/me/file.txt", encoding: NSUTF8StringEncoding)
}
}
最后我将NSString
替换为String
,因为我们使用的是Swift,而不是Objective-C; - )
答案 1 :(得分:12)
您可以使用failable initializer,因为它更适合此类情景。
class FileClass {
let text: String
init?() {
guard let fileContents = try? NSString( contentsOfFile: "/Users/me/file.txt", encoding: NSUTF8StringEncoding ) else {
text = ""
return nil
}
text = fileContents as String
}
}
或者,如果要打印错误:
class FileClass {
let text: String
init?() {
do {
text = try String( contentsOfFile: "/Users/me/file.txt", encoding: NSUTF8StringEncoding )
} catch let error as NSError {
print("Error while reading: \(error)")
text = ""
return nil
}
}
}
使用比使用投放初始化程序更容易,因为您可以使用if-let
或guard-let
:
if let file = FileClass() {
}
,或
guard let file = FileClass() else {
return
}
与
let file: FileClass
do {
file = FileClass()
} catch {
}