我看过类似的问题,但我没有看到我满意的答案.
是否可以或建议通过引用传递结构?如果是这样的话?
以下是代码作为示例的参考:
struct MyData {
var contentId: Int = 0
var authorId: Int = 0
var image: UIImage = UIImage(named: "myimage")
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我这样做的主要原因是因为没有让我的图像遍布整个地方.
Rik*_*son 40
可以使用inout关键字和&运算符通过引用传递结构.
struct Test {
var val1:Int
let val2:String
init(v1: Int, v2: String) {
val1 = v1
val2 = v2
}
}
var myTest = Test(v1: 42, v2: "fred")
func change(test: inout Test) {
// you can mutate "var" members of the struct
test.val1 = 24
// or replace the struct entirely
test = Test(v1: 10, v2: "joe")
}
change(test: &myTest)
myTest // shows val1=10, val2=joe in the playground
Run Code Online (Sandbox Code Playgroud)
除非您能证明这是在紧急情况下获得所需性能的唯一途径,否则不鼓励这种做法.
请注意,这样做不会节省复制UIImage的负担.将引用类型作为结构的成员放置时,仍然只能在按值传递时复制引用.您没有复制图像的内容.
关于struct性能的另一个重要事项是copy-on-write.像Array这样的许多内置类型都是值类型,但它们非常高效.当你在Swift中传递一个结构时,你不会承担复制它的负担,直到你改变它.
首先,如果传递结构,则通常按值传递。即使该结构的所有属性都仅被复制了指向诸如UIImage之类的引用类型的属性的指针,也被重复了(仅8个字节):
var data1 = MyData()
var data2 = data1
// both data1 and data2 point to the same image
Run Code Online (Sandbox Code Playgroud)
此外,编译器还会优化代码,以便结构在内部通过引用传递并在需要时进行复制。
作为在顶级代码中按引用传递结构的示例,您可以使用inout参数:因此,inout可以按引用传递参数,但是Swift的一般实现方式inout是按值传递参数,并在函数返回后对其进行重新分配。
尽管编译器优化了函数调用,但在某些情况下仍可以得到真正的引用。此优化仅影响未计算的变量或具有诸如willSet和didSet(可能还有其他情况)的属性观察器的变量。
因此,您应该仅依赖当前实例,该实例不在函数范围之内:
struct Test {
var value = 0
}
// case 1
var myTest = Test()
// case 2
var myTest = Test() {
didSet { print("I was set") }
}
// case 3
var myTest: Test {
get{ return Test() }
set{ print("I set myself") }
}
func mutateTest(inout t: Test) {
// directly referencing to myTest
myTest.value // value = 0 in all cases
t.value = 42
myTest.value // value = 42 in case 1 ; value = 0 in case 2 and 3
t = Test() // nothing gets printed
myTest.value // value = 0 in all cases
t = Test() // nothing gets printed
t.value = 3 // value = 3 in case 1 ; value = 0 in case 2 and 3
}
changeTest(&myTest)
//case 2: "I was set", case 3 "I set myself" get printed now
myTest.value // value = 3 in all cases
Run Code Online (Sandbox Code Playgroud)
如您所见myTest,t并且仅在情况1中等效(“ true”参考语义)。因此,如果您还引用myTest函数本身,则将产生巨大的差异。但是,只要您不这样做,就可以继续前进。
| 归档时间: |
|
| 查看次数: |
18024 次 |
| 最近记录: |