Home > Software design >  How can I alter a variable within a struct (swift)?
How can I alter a variable within a struct (swift)?

Time:08-24

I have the following code:

struct Quiz {
    
    var gender = "she"
    

    var quizQuestions = ["Is \(gender) nice?", "Is \(gender) great?", "Is \(gender) wonderful?"]
    
}

But I get the following error message:

Cannot use instance member 'gender' within property initializer; property initializers run before 'self' is available

Is there any way to alter this variable within the struct? I'm a novice with Swift - I'm trying to make a quiz app where the questions are contained in a struct. The first step for a user is to choose 'male/female', and so from then on the quiz questions should reflect that choice. I could create another struct with the same questions with the opposite gender pronouns, but this seems like a waste of space. I want one 'quizQuestions' array that will reflect the correct gender choice from an independent UIbutton. So any advice in general on how to approach this would be great. TIA.

CodePudding user response:

quizQuestions could be changed to a computed property which means the value will be created when the property is accessed and not when the object is created.

var quizQuestions: [String] {
    ["Is \(gender) nice?", "Is \(gender) great?", "Is \(gender) wonderful?"]
}

Example

var q = Quiz()
print(q.quizQuestions)
q.gender = "he"
print(q.quizQuestions)

["Is she nice?", "Is she great?", "Is she wonderful?"]
["Is he nice?", "Is he great?", "Is he wonderful?"]

Another option is to skip the property all together and use a static function to return the question, here I have also combined it with an enum for gender which of course also can (should) be used with the first solution

enum Gender: String {
    case he, she //...
}

static func quizQuestions(for gender: Gender) -> [String] {
    ["Is \(gender.rawValue) nice?", "Is \(gender.rawValue) great?", "Is \(gender.rawValue) wonderful?"]
}

Example

print(Quiz.quizQuestions(for: .she))

["Is she nice?", "Is she great?", "Is she wonderful?"]

CodePudding user response:

In addition to the answers for How to alter part of an array element in Swift?

You can make your variable var quizQuestions lazy so that it's only computed when needed:

struct Quiz {
    
    var gender = "she"
    

    lazy var quizQuestions = ["Is \(gender) nice?", "Is \(gender) great?", "Is \(gender) wonderful?"]
    
}

But here you have another issue which is you've defined a type Quiz, with such particular values that make it like a particular single value of Quiz rather than Quizzes in general, so for example if you change it to:

struct Quiz {
  var gender: String
  var questions: [String]
}

You can then see how the type Quiz starts to represent something that's not just a particular Quiz, just like the type Int doesn't represent a particular number like 3, or the type String doesn't represent a particular string like "hello".

let isNicePersonQuiz = Quiz(gender: "she", questions: ["Is she great?"...

and indeed you can then drop the gender var from Quiz and just use it when you calculate the questions

  • Related