Krakke93
Krakke93

Reputation: 95

Why can't a constant property of a struct be used in a following example

I have a following code from the Swift Design Patterns book:

protocol Identifiable {
    associatedtype ID
    static var idKey: WritableKeyPath<Self, ID> { get }
}

struct Book: Identifiable {
    static let idKey = \Book.isbn
    var isbn: String
    var title: String
}

It works fine. However, if I change the Book declaration using let instead of var for the isbn property, I receive an error: Type 'Book' does not conform to protocol 'Identifiable'. So the whole erroneous code looks like:

protocol Identifiable {
    associatedtype ID
    static var idKey: WritableKeyPath<Self, ID> { get }
}

struct Book: Identifiable {    // error: Type 'Book' does not conform to protocol 'Identifiable'
    static let idKey = \Book.isbn
    let isbn: String
    var title: String
}

I'm curious why does this happen. I try to run the code inside Xcode Playground file.

Upvotes: 1

Views: 123

Answers (1)

TomerBu
TomerBu

Reputation: 1503

It's a WritableKeyPath - you need to write to it. It must be a variable in order to be writable.

In your Book struct you are instantiating a KeyPath with a literal. This fails when the KeyPath is not a WritableKeyPath

From the docs: "A key path that supports reading from and writing to the resulting value."

Meaning that the underlying value must be a variable.

The Following does compile:

import UIKit


//https://iswift.org/playground?ZEJ6cL&v=4

protocol Identifiable {
    associatedtype ID
    static var idKey: WritableKeyPath<Self, ID> { get }
}

struct Book: Identifiable {
    static let idKey = \Book.title
    let isbn: String
    var title: String
}

Upvotes: 1

Related Questions