如何通过引用传递结构?
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
【讨论】:
以上是关于如何通过引用传递结构?的主要内容,如果未能解决你的问题,请参考以下文章