【问题标题】:How to pass structure by reference?如何通过引用传递结构?
【发布时间】:2014-12-13 17:46:01
【问题描述】:

如果我有一些现有的结构,但我想使用“引用”行为,我该如何实现?

我可以写一些简单的类持有者,比如

class Box<T> {
    var value: T
    init(_ value: T) {
        self.value = value
    }
}

我猜标准库里肯定有现成的类,但是没找到。

我想将该引用存储在我的类中,所以 inout 参数不是我需要的。

【问题讨论】:

  • class 会更适合您的目的吗?它们是通过引用传递的。 struct 的实例设计为按值传递。
  • 这将解决我的问题,但这意味着我必须复制现有的框架结构,如 CGRect 并实现来回转换。如果可能的话,我想避免重复。
  • @sapi: Swift 中的一切都是通过值传递的,除非参数被标记为inout,在这种情况下它总是通过引用传递。
  • @newacct 基本上,inout 参数不是“call-by-reference”,而是"call-by-copy-restore"

标签: swift struct pass-by-reference


【解决方案1】:

对我来说,最好的变体是使用类持有者:

class Ref<T> {
  var value: T

  init(_ value: T) {
    self.value = value
  }
}

【讨论】:

    【解决方案2】:

    你可以,但你不应该把它存储在你的班级里。

    struct Size {
        var width:Float
        var height:Float
    }
    
    class Rect {
        var sizeRef:UnsafeMutablePointer<Size>
        init(_ size:UnsafeMutablePointer<Size>) {
            self.sizeRef = size
        }
        func doubleSize() {
            self.sizeRef.memory.height *= 2.0
            self.sizeRef.memory.width *= 2.0
        }
    }  
    
    var size = Size(width: 20.0, height: 20.0)
    let rect = Rect(&size)
    rect.doubleSize()
    println("size: \(size.width) x \(size.height)") // -> size: 40.0 x 40.0
    

    因为通常,struct 是从“堆栈”内存中分配的,所以当您这样做时:

    func makeRect() -> Rect {
        var size = Size(width: 20.0, height: 20.0)
        return Rect(&size)
    }
    
    let rect = makeRect()
    

    rect.sizeRef 不再指向有效内存。 UnsafeMutablePointer 在字面上是不安全

    【讨论】:

      【解决方案3】:

      我用这个:

      @propertyWrapper public struct Inout<T> {
          public init(wrappedValue: T) {
              storage = .init(value: wrappedValue)
          }
          
          private let storage: Storage
          
          public var wrappedValue: T {
              nonmutating get { storage.value }
              nonmutating set { storage.value = newValue }
          }
          
          private class Storage {
              init(value: T) {
                  self.value = value
              }
              
              var value: T
          }
      }
      

      例子:

      struct Example { 
          init(value: Inout<Int>) { 
              _value = value
          }
          
          @Inout var value: Int
          
          func performAction() { 
              value += 19
          }
      }
      let value = Inout(wrappedValue: 50)
      let example = Example(value: value)
      example.performAction()
      print(value.wrappedValue) // 69
      

      【讨论】:

        猜你喜欢
        • 2013-06-04
        • 1970-01-01
        • 2013-05-12
        • 2011-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多