Swift中类实例属性修改后集合求和未更新的解决方法咨询
嘿,我来帮你搞定这个问题!你的代码修改a1.x后总和没变化,核心原因要么是语法错误没利用好Swift类的引用特性,要么是你可能误把class写成了struct(值类型)。下面一步步给你讲清楚:
先修正原代码的语法问题(让类的引用特性生效)
首先,Swift里类型名要大写,int得改成Int;另外,你的初始化方法定义了外部参数标签,直接写A(1,2)会编译报错,要么加上标签A(x:1, y:2),要么修改初始化方法去掉外部标签,后者用起来更顺手:
// 修正后的class A class A { var x = 0 var y = 0 // 去掉外部参数标签,初始化时直接传值就行 init(_ vx: Int, _ vy: Int) { x = vx y = vy } } class B { var a_array: [A] init() { a_array = [] } func append(_ a: A) { a_array.append(a) } func sum_all() { var sum = 0 for a in a_array { sum += (a.x + a.y) } print("sum all is", sum) } } // 测试一下 var a1 = A(1, 2) var a2 = A(3, 4) var b = B() b.append(a1) b.append(a2) b.sum_all() // 输出10 a1.x = 2 b.sum_all() // 现在就会输出11啦!
为什么这样改就有用了?
Swift里的class是引用类型,和C语言里的指针逻辑差不多:当你把a1传给b.append(a1)时,数组里存的不是a1的副本,而是指向同一个A实例的“引用”。所以你修改a1.x,本质上是修改了这个共享实例的属性,数组里的元素指向的还是同一个实例,计算总和自然会拿到更新后的值。
如果必须用值类型(比如struct)怎么办?
要是你因为业务需求必须用struct(struct是值类型,默认传副本),可以用一个简单的包装类来模拟引用传递:
// 写个通用的包装类,把值类型包起来 class Box<T> { var value: T init(_ value: T) { self.value = value } } struct A { // 这里是值类型的struct var x = 0 var y = 0 init(_ vx: Int, _ vy: Int) { x = vx y = vy } } class B { var a_array: [Box<A>] // 存包装类的引用 init() { a_array = [] } func append(_ a: Box<A>) { a_array.append(a) } func sum_all() { var sum = 0 for box in a_array { sum += (box.value.x + box.value.y) } print("sum all is", sum) } } // 测试代码 var a1 = Box(A(1, 2)) var a2 = Box(A(3, 4)) var b = B() b.append(a1) b.append(a2) b.sum_all() // 输出10 a1.value.x = 2 b.sum_all() // 输出11
总结一下
- 直接用
class就能实现类似C指针的引用效果,只要语法正确,根本不用额外操作。 - 要是非得用
struct,就用包装类把它包起来,避免传值时产生副本。
内容的提问来源于stack exchange,提问作者michaelma
相关产品推荐
相关产品推荐

