Home > Software design >  how to assign value to a get-only property
how to assign value to a get-only property

Time:09-21

As the movie struct shows as below, I want to upload my vote vault through the upVote function but the error occurs as "Cannot assign to property: 'vote' is a get-only property".

Except for the vote and 'isFavored, other properties are all decoded from a local JSON file.

my struct


struct Movie:Codable,Identifiable{
    let id=UUID()
    let MOVIE_ID:String
    let NAME:String
    let ALIAS:String
    let ACTORS:String
    let COVER:String
    let DIRECTORS:String
    let DOUBAN_SCORE:String
    let DOUBAN_VOTES:String
    let GENRES:String
    let IMDB_ID:String
    let LANGUAGES:String
    let DIRECTOR_IDS:String
\\my own property:
    var isFavered:Bool = false
\\init the vote
    var vote:Int{
        if let v = Int(DOUBAN_VOTES){
            return v
        }else{
            return 0
        }
        
    }
    enum CodingKeys: String, CodingKey {
        case MOVIE_ID, NAME,ALIAS,ACTORS,COVER,DIRECTORS,DOUBAN_SCORE
        case DOUBAN_VOTES,GENRES,IMDB_ID,LANGUAGES,MINS,OFFICIAL_SITE
        case REGIONS,RELEASE_DATE,SLUG,STORYLINE,TAGS,YEAR,ACTOR_IDS,DIRECTOR_IDS
    }
\\my uploade vote function
    func upVote(newVote:Int){
        vote = newVote \\ here occurs the error
    }
}

CodePudding user response:

You first need to declare DOUBAN_VOTES as mutable and then change the computed property to be mutable. By using private(set) for DOUBAN_VOTES it will be immutable outside of the struct.

private(set) var DOUBAN_VOTES: String

var vote: Int {
  get {
    return Int(DOUBAN_VOTES) ?? 0
  }
  set {
    DOUBAN_VOTES = String(newValue)
  }
}

CodePudding user response:

You have two problems.

First, as you have discovered, you can't modify vote because it is a computed property. Its value is determined by the code in its getter method. Assigning a value doesn't make sense.

I guess you have used a computed property because your JSON source is, frankly, awful. Integers should be sent as integers, not strings.

Assuming you can't change the JSON to something more sensible, then you will just need to update the underlying DOUBAN_VOTES property in your upVote function. You will need to make DOUBAN_VOTES a var, not a let.

This will reveal your second problem; Structs are immutable. In order to allow a function to change a value, it must be flagged as a mutating function.


var DOUBAN_VOTES:String

mutating func upVote(newVote: Int) {
    self.DOUBAN_VOTES = "\(newVote)"
}
  • Related