The first solution is to provide a new init method that copies the current instance. This approach is called a copy constructor. Let's add our new init method and leverage it:
init(products: [FunctionalProduct], lastModified: Date) {
self.products = products
self.lastModified = lastModified
}
init(productTracker: FunctionalProductTracker,
products: [FunctionalProduct]? = nil,
lastModified: Date? = nil) {
self.products = products ?? productTracker.products
self.lastModified = lastModified ?? productTracker.lastModified
}
We added the default init as well because by adding a new init method to our struct, we lost the benefit of automatic init generation. We also need to change our addNewProduct to accommodate these following changes:
func addNewProduct(item: FunctionalProduct) -> FunctionalProductTracker {
return FunctionalProductTracker(productTracker: self,
products: self.products + [item])
}
Whenever we need to modify our object partially, we will be able to do so easily using this technique.