【问题标题】:Swift variable declaration meaningSwift变量声明意义
【发布时间】:2015-02-15 08:23:38
【问题描述】:

这两个声明有什么区别?哪一个更好?为什么?

... error = some NSError ...

1.

var newUserInfo: [NSObject: NSObject] = [:]

if let tempUserInfo = error.userInfo as? [NSObject: NSObject] {
  newUserInfo = tempUserInfo
}

2.

var newUserInfo: [NSObject: NSObject]

if let tempUserInfo = error.userInfo as? [NSObject: NSObject] {
  newUserInfo = tempUserInfo
} else {
  newUserInfo = [:]
}

【问题讨论】:

    标签: swift memory-management


    【解决方案1】:

    从 Swift 1.2 开始,您现在可以将 let 与延迟赋值一起使用,以便您可以使用 if/else 版本:

    let newUserInfo: [NSObject: NSObject]
    
    if let tempUserInfo = error.userInfo as? [NSObject: NSObject] {
      newUserInfo = tempUserInfo
    } else {
      newUserInfo = [:]
    }
    

    但是,选项 1不起作用,因为有一条路径可能无法设置 newUserInfo

    (注意,从 1.2b1 开始,这不适用于全局变量,仅适用于成员和局部变量,以防你在操场上尝试)

    或者,您可以使用 nil-coalescing 运算符一次性完成,如下所示:

    let newUserInfo = (error.userInfo as? [NSObject:NSObject]) ?? [:]
    

    编辑:Swift 1.2 添加了 let 的延迟分配,现在可以将选项 2 与 let 一起使用,但也更改了 as??? 的优先级,需要括号。

    1.2 之前的答案,以防您有类似的代码需要迁移:

    如果你问我,两者都不是特别吸引人。在这两种情况下,您都必须声明 newUserInfovar,因为您不是一次性声明和分配它。

    我建议:

    let newUserInfo = error.userInfo as? [NSObject:NSObject] ?? [:]
    

    【讨论】:

    【解决方案2】:
    • 在 1. 如果if 分支被执行,newUserInfo 被分配两次。 2. 在性能方面更好
    • 在 1. 中可以清楚地看到newUserInfo 被初始化为一个空数组。 2. 降低代码的可读性,因为你必须浏览代码才能知道它是否有默认值
    • 如果newUserInfo可以在多个地方设置(比如可以在多个if语句中初始化),你应该复制2.中的else分支,这样1.看起来更好

    所以:在解决方案中没有。 1 代码更具可读性,但没有解决方案。 2 的性能稍高一些。

    除了使用@AirspeedVelocity 解决方案(这比你的更好,没有冒犯:)),我宁愿使用可选,将newUserInfo 设置为nil 以表示没有价值-毕竟,这就是可选项的用途,不是吗?但这当然取决于您的具体需求。

    【讨论】:

      【解决方案3】:

      我的首选模式是:

      struct TryUnrap<T> {
          typealias Tryee = () -> T?
          typealias Catchee = () -> T
      
          private var tryee: Tryee
      
          init(tryee: Tryee) {
              self.tryee = tryee
          }
      
          func catch(catchee: Catchee) -> T {
              if let result = tryee() {
                  return result
              }
              return catchee()
          }
      }
      
      let error: NSError? = NSError()
      let newUserInfo = TryUnrap {
          error?.userInfo as? [NSObject : NSObject]
      }.catch {
          [:]
      }
      println("newUserInfo = \(newUserInfo)")
      

      我更喜欢上面的,因为我觉得它读起来更适合我。另请参阅Error-Handling in Swift-Language 的答案 4,了解使用相同模式的一般错误处理。

      【讨论】:

      • 这本质上是?? 的非惯用低效实现,用于恢复 Java 程序员。
      • 对我来说它看起来比其他人更难读,我更喜欢第一个答案......但这是个人的。
      • 我没找到??非常易读,也不能用于其他 try catch 情况。不过这是个人口味的问题。效率几乎可以肯定是无关紧要的,您正在初始化一个根据定义是一次性的 let。
      猜你喜欢
      • 2015-03-27
      • 1970-01-01
      • 2018-02-20
      • 2011-04-30
      • 1970-01-01
      • 2011-01-06
      • 2011-09-17
      • 2011-09-25
      • 1970-01-01
      相关资源
      最近更新 更多