如果在将类文件加载到类中的字符串时出现问题,我希望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
我得到一个类实例的所有存储属性必须在从初始化器错误抛出之前初始化.
我尝试了各种方法,例如使文本可选
let text: NSString?
但没有找到任何工作.它可以从文件加载文本,不可变,并为init()抛出错误?我可以吃蛋糕吗?
提前谢谢了!
从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 ;-)
您可以使用可用的初始化程序,因为它更适合这种情况.
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 } } }
使用比使用throw初始化程序更容易,因为您可以使用if-let
或guard-let
:
if let file = FileClass() { }
, 要么
guard let file = FileClass() else { return }
与
let file: FileClass do { file = FileClass() } catch { }