Arsen
Arsen

Reputation: 10951

Swift immutable struct and convenient update

I have a struct

struct Offer {
    let offerId: Int
    let title: String
    let description: String
    let phoneNumber: String
    let address: String
    let createdAt: NSDate
    let price: Float
    let type: String
    let quantity: Int
    let instructions: [String]
    let votesCount: Int
    let featured: Bool
    let published: Bool
    let publishable: Bool
    let voted: Bool
    let user: PublicProfile
    let images: [OfferImage2]
    let imageIds: [String: Int]
    let featuredImage: String
    let countries: [String]

    var featuredAt: NSDate?
    var featuredTill: NSDate?
    var publishedAt: NSDate?

And I want to keep it immutable (use let instead of var when possible) but I have a problem. When I need to update a property I do following:

mutating func updateTitle(_title: String) {
        self = Offer(offerId: offerId, title: _title, description: description, phoneNumber: phoneNumber, address: address, createdAt: createdAt, price: price, type: type, quantity: quantity, instructions: instructions, votesCount: votesCount, featured: featured, published: published, publishable: publishable, voted: voted, user: user, images: images, imageIds: imageIds, featuredImage: featuredImage, countries: countries, featuredAt: featuredAt, featuredTill: featuredTill, publishedAt: publishedAt)
}

It works but I'm looking for more compact way to do this.

Upvotes: 3

Views: 634

Answers (1)

Matan Lachmish
Matan Lachmish

Reputation: 1263

There is a tiny problem with your request:

I want to keep it immutable

Don't go along with:

When I need to update a property

If you meant by that that you don't want to allow to change this property from outside there is more elegant way.

You can make the setter private.

In Offer.swift (you can set the title anywhere):

struct Offer {
    let offerId: Int
    private(set) var title: String

    mutating func updateTitle(title: String) {
        self.title = title
    }
}

In OtherClass.swift (you are not allowed to set the title):

    var offer = Offer.init(offerId: 123, title: "Offer1")
    offer.title = "Offer2" //- Compilation error "Cannot assign to property: 'title' setter is inaccessible"

Upvotes: 2

Related Questions