【问题标题】:Append a struct inside a property which is an array inside other struct in Swift在属性中附加一个结构,该属性是 Swift 中其他结构中的一个数组
【发布时间】:2016-12-19 13:47:03
【问题描述】:

嗨,我需要在一个数组中附加一个结构,它是另一个结构的属性,我使用的是 Swift 3,但是没有附加任何东西,我不知道为什么,请帮忙?

import Foundation

struct Product {
    var objectId: String
    var name: String
    var price: Double
    var qty: Int
    var img: String
    var desc: String
    var note: String
}

struct Order {
    var objectId: String
    var name: String
    var detail: [Product]
    mutating func addToDetail(_ product: Product) {
        detail.append(product)
    }
}

class OrderManager: NSObject {

    static let shared = OrderManager()

    var order: Order?

    var orderCreated: Bool {
        return self.order != nil
    }

    var partnerInOrder: String? {
        return self.order?.objectId
    }

    func createOrderIfNeeded(partnerId: String, name: String) {
        if self.order == nil {
            self.order = Order(objectId: partnerId, name: name, detail: [Product]())
        }

    }

    func addProduct(objectId: String, name: String, price: Double, qty: Int, img: String = "", desc: String = "", note: String = "") {
        guard var order = self.order else {
            return
        }

        let hasProduct = order.detail.contains(where: { $0.objectId == objectId })

        if !hasProduct {
            order.addToDetail(Product(objectId: objectId, name: name, price: price, qty: qty, img: img, desc: desc, note: note))
        }

        print("has product \(hasProduct)")
        print("the whole order is \(self.order)")
    }


    func addOption() {}

    func getProduct() {}

    func getOption() {}

    fileprivate func storeOrder() {}

}

正在进入结构的 addToDetail 函数,但我的数组始终为空

【问题讨论】:

  • 是的,我什至注释了每次调用函数的if,但仍然是空的,奇怪!
  • 你能不能在addToDetail方法里面放一个断点,看看数组是被分配了还是还是nil?

标签: arrays swift struct


【解决方案1】:

在以下guard 语句中(在OrderManager 的方法addProduct 中)

guard var order = self.order else { /* ... */ }

由于 Swift 中结构的值语义,您创建了 self.order副本(假设它不是 nil)。随后对 addToDetail 的调用 此副本 不会将 Product 实例附加到 self 的实例变量 order,而只会附加到超出范围的副本 @987654331 @ 超出范围。

您可以通过用简单的nil 检查替换上面guard 语句中的可选绑定子句来测试这个理论(正如@MartinR 在下面指出的那样,我们真的不需要guard 语句(在修复:没有绑定),但如果self.ordernil,则可以提前执行return

if self.order == nil { return }

或者,完全删除显式的nil 检查,并使用可选链接来决定是否将product 添加到order 实例(将nil 检查和hasProduct 组合成一个可选的链接子句):

func addProduct(objectId: String, name: String, price: Double, qty: Int, img: String = "", desc: String = "", note: String = "") {
    if !(self.order?.detail.contains(where: { $0.objectId == objectId }) ?? true) {
        order?.addToDetail(Product(objectId: objectId, name: name, price: price, qty: qty, img: img, desc: desc, note: note))
    }
    // ... remove the logging
} 

不过,这在显示代码意图方面做得更差。

【讨论】:

  • 是啊!!,你是个好人,当然我怎么没看到,谢谢!还有守卫的例子,非常好,再次感谢!!!
  • guard self.order != nil else {...} 这是检查非零可选的首选方法。
  • @Abizern 这也是一个(更常见的)替代方案;我自己喜欢使用模式匹配方法(尽管再次显式检查nil 可能有更多的意图显示语义)。感谢您的反馈。
  • 为什么不简单地if self.order == nil { return }
  • @MartinR 是的,为什么不:D guard 声明过度使用失明(我自己)。
猜你喜欢
  • 2021-11-10
  • 2016-01-21
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
  • 1970-01-01
  • 2021-04-12
  • 2016-11-04
相关资源
最近更新 更多