在Swift中在For循环内更改对象的属性 [英] Changing Object's Properties Inside For Loop in Swift

查看:146
本文介绍了在Swift中在For循环内更改对象的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个名为ShoppingList的简单结构.

I created a simple struct called ShoppingList.

struct ShoppingList {

    var shoppingListId :NSNumber
    var title :String
    var groceryItems :[GroceryItem]

    init() {
        self.title = ""
        self.groceryItems = [GroceryItem]()
        self.shoppingListId = NSNumber(integer: 0)
    }

}

接下来,我创建了一个ShoppingList数组,如下所示:

Next I created a ShoppingList array like this:

 var shoppingLists = [ShoppingList]()

此后,我获取购物清单等.现在,我遍历shoppingLists并更改标题,但它会更新title属性.

After that I fetch the shopping lists etc. Now, I iterate through the shoppingLists and change the title but it ever updates the title property.

 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循环更改原始数组?

I believe that when I am running the loop it is copying by value and hence the original array is never changed. How can I change the original array using For loop?

推荐答案

在这里我将使用两种方法.第一种方法是重新考虑 ShoppingList 是值类型还是引用类型.它具有标识符的事实向我表明,它实际上是引用类型.如果两个购物清单的内容相同,是否应将其视为相同的清单?我怀疑不是.具有相同标识符但内容不同的两个列表意味着什么?再次,如果那是非法的,那往往会指出它是引用类型,因为它具有身份.

There are two approaches I would use here. The first approach is to reconsider whether ShoppingList is a value type or a reference type. The fact that it has an identifier suggests to me that it's really a reference type. If two shopping lists have the same contents, should the be considered the same list? I suspect not. What would it mean to have two lists that have the same identifier, but different contents? If that's illegal, again, that tends to point to it being a reference type because it has an identity.

如果是引用类型,则将其设置为最终类:

If it's a reference type, make it a final class:

final class ShoppingList {}

最终类保留了结构的简单性,因为它们没有继承问题.但是它们提供了参考语义.进行此更改后,您的原始代码就可以使用.

Final classes preserve the simplicity of structs because they do not suffer the problems of inheritance. But they provide reference semantics. With that change, your original code would work.

解决此问题的另一种方法是更具功能性,其中一切都是价值.在这种情况下,您可以通过映射购物清单的副本来实现:

The other way to approach this is more functional, where everything is a value. In that case, you can achieve this by mapping copies of your shopping lists:

shoppingLists = shoppingLists.map { list in
    var newList = list
    newList.groceryItems = getGroceryItemsByShoppingList(list)
    return newList
}

这将我们推向了一种更具功能性的方法,但是它使标识符变得笨拙.因此,如果您真的想这样做,我想摆脱标识符,甚至可以使购物清单不可变.在这种情况下,任何两个相同的购物清单都是相同的清单,并且您可以使用更具功能性的样式进行书写.

This pushes us towards a more functional approach, but it makes the identifier awkward. So if you really wanted to go this way, I'd want to get rid of identifiers and maybe even make shopping lists immutable. In that case, any two identical shopping lists are the same list, and you can write in a more functional style.

但是我怀疑将 ShoppingList 用作引用类型是您更好的方法.

But I suspect that making ShoppingList a reference type is your better approach.

这篇关于在Swift中在For循环内更改对象的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆