【问题标题】:How to avoid "Variable j written into, but never read" in Swift?如何在 Swift 中避免“变量 j 写入,但从未读取”?
【发布时间】:2016-10-02 07:15:12
【问题描述】:

我正在使用变量 j 在 defer 块中打印其最终值,如下所示:

func justForFun()
{    
   defer {let x = j; print("\(x)")}
   var j = 0
   for i in 1...5
   {
       print("\(i)")
       j = i*2;
   }
}
justForFun()

所以,变量 j 确实在 defer 块中被读取和打印。尽管如此,PlayGround 仍显示 变量 j 已写入但从未读取的警告。有没有办法启发编译器并消除此警告?

【问题讨论】:

    标签: swift3 swift-playground


    【解决方案1】:

    如果将变量声明移到defer 上方,警告就会消失。

    $ cat d.swift 
    func justForFun() {    
       var j = 0
       defer {let x = j; print("\(x)")}
       for i in 1...5 {
           print("\(i)")
           j = i*2;
       }
    }
    justForFun()
    
    $ swift d.swift 
    1 
    2
    3
    4
    5
    10
    

    虽然这不能解释为什么出现警告,但它确实回答了如何使警告消失。

    就启发编译器而言,我认为您无法做到这一点。您可能想在 swift.org 上提交和发布;请参阅this page 了解如何报告错误。似乎静态流检查器没有查看defer 语句,我认为应该这样做。很好的发现。

    【讨论】:

    • 有没有办法给这个答案打一个“半勾”标记,因为它已经回答了我问题的第一部分?如果没有其他问题,我想把它转换为全勾回答或者如果我的第二部分问题是 Swift 3 中的一个已知错误。
    • 这是个好问题。如果对您没有帮助,请不要投票。您可以等待答案或尝试 Swift 论坛或发布错误报告,看看开发人员怎么说。对我来说似乎是一个错误,但我不能肯定地告诉你。
    • 我已经等了四天,并将其作为错误提交到您指定的站点中。我完全相信会给你打上完整的勾号。
    • 希望你能找到答案。这是一个有趣的案例。如果 Swift 会采用这样的规则,即本地的范围从声明点延伸到块的末尾,那么我会预料到一个编译器错误,说在 defer 块中使用 j 是不在范围内。出现警告的事实很奇怪。
    【解决方案2】:

    解决方法

    添加匿名分配_ = 可消除警告:

    // Swift 3.0
    func justForFun()
    {
      defer {let x = j; print("\(x)")}
      var j = 0
    
      // anonymous assignment:
      _ = j
      for i in 1...5
      {
        print("\(i)")
        j = i*2;
      }
    }
    
    justForFun()
    

    【讨论】:

    • 我很抱歉。我无法理解您的评论“至于....石头”。请转述。
    • 虽然我不默认在 SO 中轻率,但在我看来,当 OP 将他的函数命名为 justForFun() 时,他设定了一种轻松的语气。但是轻松!=令人困惑。我已经删除了那条线。
    猜你喜欢
    • 2016-10-24
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多