在Swift中,如果optional是nil,则初始化非可选var的最佳方法

时间:2017-10-25 14:33:09

标签: swift optional

我想通过从obj获取变量UserDefaults来初始化变量String?,它返回nil,如果它是obj则构建值并分配它。< / p>

以下代码有效,但最后,我的String?String,而我希望它是nil(因为它不能是var obj = UserDefaults.standard.string(forKey: "my_key")// Here, obj is a String? if obj == nil { obj = ProcessInfo.processInfo.globallyUniqueString// Returns, a String defaults.set(obj, forKey: "my_key") defaults.synchronize() } // Here, obj is still a String? 在这个阶段)。

Info.plist

这种情况是否有良好的模式/最佳实践?

4 个答案:

答案 0 :(得分:5)

你可以使用nil-coalescing运算符?? “立即评估关闭”:

let obj = UserDefaults.standard.string(forKey: "my_key") ?? {
    let obj = ProcessInfo.processInfo.globallyUniqueString
    UserDefaults.standard.set(obj, forKey: "my_key")
    return obj
}()

print(obj) // Type is `String`

如果未设置用户默认值,则执行闭包。 闭包创建并设置用户默认值(使用 local obj 变量)并将其返回给调用者,以便 它被分配给外部obj变量。

答案 1 :(得分:2)

可选绑定。您可以阅读here

let obj: String

if let string = UserDefaults.standard.string(forKey: "my_key") {
    obj = string
} else {
    obj = ProcessInfo.processInfo.globallyUniqueString
    UserDefaults.standard.set(obj, forKey: "my_key")
}

print(obj)

答案 2 :(得分:1)

使用guard letif let

1) guard let (但不适用于您的情况)

guard let obj = UserDefaults.standard.string(forKey: "my_key") else { 
    // guard failed - obj is nil; perform something and return
    obj =  ProcessInfo.processInfo.globallyUniqueString
    defaults.set(obj, forKey: "my_key")
    return 
}

// obj is not nil, you have it at your disposal
print(obj)

2) if let

if let obj = UserDefaults.standard.string(forKey: "my_key") {
   // obj exists
} else {
    let obj =  ProcessInfo.processInfo.globallyUniqueString
    defaults.set(obj, forKey: "my_key")
    print(obj)
} 

(!)此外,确实不再需要致电defaults.synchronize()

  

等待默认数据库的任何挂起的异步更新   并返回;这种方法是不必要的,不应该使用。

     

<子> https://developer.apple.com/documentation/foundation/nsuserdefaults/1414005-synchronize

答案 3 :(得分:1)

您还可以使用隐式展开的可选项,如下所示:

var obj: String! = UserDefaults.standard.string(forKey: "my_key")// Here, obj is a (possibly `nil`) `String!`
if obj == nil {
    obj =  ProcessInfo.processInfo.globallyUniqueString // Returns, a String
    defaults.set(obj, forKey: "my_key")
    defaults.synchronize()
}

// Here, obj is a non-`nil` `String!`, which will work the same as a `String`