Cannot assign to property: 'xxxx' is a get-only property

invisible squirrel picture invisible squirrel · May 21, 2017 · Viewed 27.9k times · Source

I'm using a computed property to get the last book in my books array. However, it seems I can't use this property to directly set a book's position property, as my attempt below shows:

struct Book {
    var position: CGPoint?
}

class ViewController: UIViewController {

    var books = [Book]()

    var currentBook: Book {
        return books[books.count - 1]
    }

    func setup() {
        // Compiler Error: Cannot assign to property: 'currentBook' is a get-only property
        currentBook.position = CGPoint.zero
    }
}

The following works but I'd like it to be more readable and a single line.

books[books.count - 1].position = CGPoint.zero

I could use a function to return the current book but using a property would be cleaner. Is there another way?

Answer

Sweeper picture Sweeper · May 21, 2017

The error occurs because you did not tell the compiler what to do if the value of currentBook is mutated. The compiler assumes it is immutable.

Just add a setter so that the compiler knows what to do when you set the value:

var currentBook: Book {
    get { return books[books.count - 1] }
    set { books[books.count - 1] = newValue }
}

Or, consider using books.last!:

books.last!.position = CGPoint.zero