【问题标题】:Reference to array inside function in Swift在 Swift 中引用函数内部的数组
【发布时间】:2015-03-01 16:53:48
【问题描述】:

我正在尝试引用函数内的数组。
像这样:abInts 的数组。

  var inout refArr = &a
  if(!someFlag) {
     refArr = &b
  }
  refArr[someIndex] = 30

这不能编译,我可以只使用inout 作为函数参数吗? 如果是这样,我如何在函数中做一个引用/指针?

【问题讨论】:

  • 你的函数的其余部分是什么样的?
  • 我正在更改数组中的值,我需要它们持久化
  • 最好的方法是在函数中只使用inout参数

标签: arrays swift reference


【解决方案1】:

& 只能用于将变量作为inout 参数传递给函数。所以最简单的解决方案可能是使用辅助函数 在你的函数内部:

func foo() {

    func helper(inout array : [Int]) {
        array[2] = 99
    }

    var a = [1, 2, 3, 5, 6]
    var b = [4, 5, 6, 7]
    let someFlag = true

    if someFlag {
        helper(&a)
    } else {
        helper(&b)
    }

    // ...
}

可以使用UnsafeMutableBufferPointer创建对数组的引用:

let ref = someFlag ?
    UnsafeMutableBufferPointer(start: &a, count: a.count) :
    UnsafeMutableBufferPointer(start: &b, count: b.count)
ref[2] = 99

但是这个解决方案有两个问题:

  • UnsafeMutableBufferPointer() 创建一个非拥有引用, 因此编译器可能决定在引用时释放数组 仍在使用。
  • 没有对数组进行边界检查。

所以为了让这项工作安全,你必须添加一些代码:

withExtendedLifetime(a) { () -> Void in
    withExtendedLifetime(b) { () -> Void in
        let ref = someFlag ?
            UnsafeMutableBufferPointer(start: &a, count: a.count) :
            UnsafeMutableBufferPointer(start: &b, count: b.count)
        if ref.count > 2 {
            ref[2] = 99
        }
    }
}

有点丑。

【讨论】:

    【解决方案2】:

    您可以在函数中使用 inout 参数来完成此操作。使用 inout 修饰符作为参数,并在将值传递给函数时使用与号 (&),如下所示:

    func swapTwoInts(inout a: Int, inout b: Int) {
        let temporaryA = a
        a = b
        b = temporaryA
    }
    
    var x = 5
    var y = 10
    
    swapTwoInts(&x, &y)
    
    x // 10
    y // 5
    

    【讨论】:

      【解决方案3】:

      swift 中的数组不能保证在内存中与它们在 C 中的方式是连续的,因此为了确保您可以访问连续块,您必须将它们传递给带有 inout 参数的函数,或者--如果你真的想在函数中引用一个数组——像这样[1]创建一个UnsafeMutableBufferPointer

      var someFlag: Bool = false
      var a = ["a", "b", "c"]
      var b = ["d", "e", "f"]
      
      var refArr = a.withUnsafeMutableBufferPointer { (inout output: UnsafeMutableBufferPointer<String>) -> UnsafeMutableBufferPointer<String> in
      
          return output
      }
      
      println(refArr[1]) //Will Output 'a'
      
      if !someFlag {
          refArr = b.withUnsafeMutableBufferPointer { (inout output: UnsafeMutableBufferPointer<String>) -> UnsafeMutableBufferPointer<String> in
      
              return output
          }
      }
      
      println(refArr[1]) //Will Output 'e'
      

      1. Thread Safety with Swift Arrays

      【讨论】:

      • withUnsafeMutableBufferPointer 创建(据我所知,不是 100% 确定),一个“非拥有”引用。所以编译器可以在引用仍然存在时释放数组 a、b。
      • 在绝大多数情况下,最好的做法似乎倾向于使用 inout 参数,如果你不需要的话,不要乱用 C 样式的引用,但是你有没有深入了解如何保留 UnsafeMutableBufferPointer 引用,如果如您所说,它们会创建一个无主引用
      猜你喜欢
      • 2016-04-24
      • 1970-01-01
      • 2011-12-28
      • 2012-08-20
      • 1970-01-01
      • 2016-01-13
      • 2015-01-22
      • 1970-01-01
      相关资源
      最近更新 更多