Swift:解包可选,否则创建新实例

时间:2017-06-18 21:38:50

标签: swift let

我正在使用let从字典中解包一个可选项,但发现处理其他情况很麻烦。

  if let d : Dog = zoo["Barky"]  {
    d.bark()
  } else {
    // Create missing Dog
    let d : Dog = Dog.init()
    zoo["Barky"] = d
    d.bark()
  }

有没有办法让这更简洁/优雅?

  • 如何将重复调用拉到bark()
  • 如何避免重复的let定义。

5 个答案:

答案 0 :(得分:1)

您可以这样使用 ?? 运算符:

let d = zoo["Barky"] ?? Dog.init()
zoo["Barky"] = d
d.bark()

在Swift 4中,词典可以有默认值。示例:

let d = zoo["Barky", default: Dog.init()]

答案 1 :(得分:1)

这个怎么样?

if zoo["Barky"] == nil {
    zoo["Barky"] = Dog()
}

zoo["Barky"]?.bark()

答案 2 :(得分:0)

一个更短的选择:

var d: Dog!= zoo["Barky"]
if d == nil {
    d = Dog()
    zoo["Barky"] = d
}
d.bark()

或(如果您不介意检查字典两次):

if zoo["Barky"] == nil {
    zoo["Barky"] = Dog()
}
zoo["Barky"]!.bark()

答案 3 :(得分:0)

你可以用两行代码制作它。 :)

let d: Dog = zoo["Barky"] ?? Dog()
zoo["Barky"] = d 
d.bark()

答案 4 :(得分:0)

谢谢大家!我在另一个答案中找到了以下片段,我喜欢:

let d = zoo["Barky"] ?? {
  let d = Dog()
  zoo["Barky"] = d
  return d
}()

由于我在很多地方都需要这个成语,所以我也延伸到了Dictionary

extension Dictionary {

    mutating func get_or_set(_ key: Key, defaultValue: () -> Value) -> Value {
        if let value = self[key] {
            return value
        } else {
            let value = defaultValue()
            self[key] = value
            return value
        }
    }
}

let d = zoo.get_or_set("Barky", defaultValue: { Dog() })

然后我发现subscript运算符也可以重载:

extension Dictionary {    
    subscript(key: Key, defaultFunc defaultFunc: () -> Value) -> Value {
        mutating get { 
            return self[key] ?? { 
                let value = defaultFunc()
                self[key] = value
                return value
            }()
        }
    }
}

var d = zoo["Barky", defaultFunc: { Dog.init() }]