我可以从Swift中的类init()抛出从文件加载的常量字符串吗?

时间:2016-01-01 22:42:24

标签: swift

如果将文件加载到类中的字符串中出现问题,我希望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()会抛出错误?我可以吃蛋糕并吃三个吗?

非常感谢提前!

2 个答案:

答案 0 :(得分:16)

[更新] Swift版本> = 2.2

从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版本< = 2.1

目前在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-letguard-let

if let file = FileClass() {
}

,或

guard let file = FileClass() else {
    return
}

let file: FileClass
do {
    file = FileClass()
} catch {
}