如何在swift中初始化结构时传递默认值

时间:2018-03-05 23:25:55

标签: ios swift

我已将此struct定义为在ErrorLogger中使用。但是,一些参数如Timestamp我想立即获得列出的功能。如何为参数传递默认值而不是nil:headererrorLocationuserId?如果没有提供其他值,则表示将使用默认值。

我的想法是,如果我将一些默认值传递给这些参数,那么将调用struct函数来获取值,否则这些值将被初始化期间用户传递的任何内容覆盖。

我也收到错误:

  

在初始化所有存储属性之前自己使用

在这一行:

self.errorLocation = getErrorLocation()

从viewController初始化struct:

let logError = LogError(header: nil, errorLocation: nil, userID: nil, description: "An error occurred while verifying if the user profile exists", errorMessage: "\(error?.localizedDescription ?? "")")
ErrorLogger中的

struct:

struct LogError {
    var header: String
    var errorLocation: String
    var userID: String
    var description: String //describes the type of error
    var errorMessage: String //actual error returned by given function

    //TODO: add timestamp to lofError
    //TODO: add logEvent (enum: Error, Info) For example: data validation errors can be of event Info

    init(header: String?, errorLocation: String?, userID: String?, description: String, errorMessage: String) {
        if header != nil {
            self.header = header!
        } else {
            self.header = " ::Error::"
        }
        if errorLocation != nil  {
            self.errorLocation = errorLocation!
        } else {
            self.errorLocation = getErrorLocation()
        }
        if userID != nil {
            self.userID = userID!
        } else {
            self.userID = getUserID()
        }
        self.description = " ::description::" + description
        self.errorMessage = " ::errorMessage::" + errorMessage
    }

    func getUserID() -> String {
        var userUID: String = ""
        if Auth.auth().currentUser != nil {
            userUID = (Auth.auth().currentUser!.uid.isEmpty ? "" : Auth.auth().currentUser!.uid)
        } else {
            userUID = ""
        }
        let userUIDStr: String = " ::UserID::" + userUID
        return userUIDStr
    }

    func getErrorLocation() -> String {

        // Get class name
        let filePath: String = #file
        let components = filePath.components(separatedBy: "/")
        let className: String = components.isEmpty ? "" : components.last!

        // Get line number
        let line: Int = #line

        // Get column number
        let column: Int = #column

        // Get function name
        let funcName: String = #function

        let errorLocationStr: String  = " ::className::\(className)::lineNumber\(line)::columnNumber\(column)::funcName::\(funcName)"

        return errorLocationStr
    }

    func toString() -> String {
        let completeLogErrorMessageStr: String = header + errorLocation + userID + description + errorMessage
        return completeLogErrorMessageStr
    }
}

1 个答案:

答案 0 :(得分:2)

在调用方法之前,必须先使所有属性有效。我会将你的init重构成这样的东西:

init(header: String?, errorLocation: String?, userID: String?, description: String, errorMessage: String) {
    self.header = header ?? " ::Error::"
    self.errorLocation = errorLocation ?? ""
    self.userID = userID ?? ""
    self.description = " ::description::" + description
    self.errorMessage = " ::errorMessage::" + errorMessage

    if errorLocation == nil  {
        self.errorLocation = getErrorLocation()
    }
    if userID == nil {
        self.userID = getUserID()
    }
}

这将修复“在初始化所有存储属性之前自行使用”错误。

要使用默认值,请更新签名:

init(header: String? = nil, errorLocation: String? = nil, userID: String? = nil, description: String, errorMessage: String) {
    // nothing else changes
}

现在您可以在没有nil参数的情况下调用初始化程序。

例如:

let logError = LogError(header: nil, errorLocation: nil, userID: nil, description: "An error occurred while verifying if the user profile exists", errorMessage: "\(error?.localizedDescription ?? "")")

变为:

let logError = LogError(description: "An error occurred while verifying if the user profile exists", errorMessage: "\(error?.localizedDescription ?? "")")