我创建了一个名为ShoppingList的简单结构.
struct ShoppingList { var shoppingListId :NSNumber var title :String var groceryItems :[GroceryItem] init() { self.title = "" self.groceryItems = [GroceryItem]() self.shoppingListId = NSNumber(integer: 0) } }
接下来,我创建了一个ShoppingList数组,如下所示:
var shoppingLists = [ShoppingList]()
之后,我获取购物清单等.现在,我遍历shoppingLists并更改标题,但它会更新title属性.
for var shoppingList in shoppingLists { let items = getGroceryItemsByShoppingList(shoppingList) shoppingList.groceryItems = getGroceryItemsByShoppingList(shoppingList) shoppingList.title = "BLAH" // copied by value print("ShoppingList \(shoppingList.title) has \(shoppingList.groceryItems.count) items") // THIS PRINT BLAH } print("shoppingLists[0].groceryItems.count \(shoppingLists[0].groceryItems.count)") // THIS PRINTS THE ORIGINAL CONTENT
我相信当我运行循环时,它是按值复制的,因此原始数组永远不会改变.如何使用For循环更改原始数组?
我会在这里使用两种方法.第一种方法是重新考虑ShoppingList
是值类型还是引用类型.它有一个标识符这一事实告诉我它确实是一个引用类型.如果两个购物清单具有相同的内容,是否应该被视为相同的列表?我怀疑不是.拥有两个具有相同标识符但内容不同的列表意味着什么?如果那是非法的,那么它往往指向它是一种引用类型,因为它具有一个身份.
如果它是引用类型,请将其设为final class
:
final class ShoppingList {}
最终类保留了结构的简单性,因为它们不会遇到继承问题.但它们提供了参考语义.通过该更改,您的原始代码将起作用.
另一种方法是更具功能性,一切都是价值.在这种情况下,您可以通过映射购物清单的副本来实现此目的:
shoppingLists = shoppingLists.map { list in var newList = list newList.groceryItems = getGroceryItemsByShoppingList(list) return newList }
这促使我们采用更具功能性的方法,但它使标识符变得尴尬.所以如果你真的想这样做,我想摆脱标识符,甚至可能使购物清单变得不可变.在这种情况下,任何两个相同的购物清单都是相同的列表,您可以用更实用的风格书写.
但我怀疑制作ShoppingList
参考类型是你更好的方法.