如何通过引用传递结构?

Posted

技术标签:

【中文标题】如何通过引用传递结构?【英文标题】: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"。 【参考方案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

【讨论】:

以上是关于如何通过引用传递结构?的主要内容,如果未能解决你的问题,请参考以下文章

通过引用 coder.ceval 在结构中传递数组

是否应该通过 const 引用传递小的简单结构?

如何通过引用从 c# 到 c++ 传递字节数组

C语言有引用传递吗

无法通过引用传递typedef结构

如何将结构成员作为引用传递给函数?