首页 文章

在Swift中引用函数内部的数组

提问于
浏览
3

我试图引用函数内的数组 .
像这样: abInt 的数组 .

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

这不编译,我可以只使用 inout 作为函数参数吗?如果是这样,我如何在函数内部执行引用/指针?

3 回答

  • 3

    & 只能用于将变量作为 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
            }
        }
    }
    

    这有点难看 .

  • 0

    您可以在函数中使用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
    
  • 0

    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

相关问题