2

I was doing one example on getters and setters the example is below

import Foundation

class person
{
    var first_name:String
    {
        get
        {
           return self.first_name
        }
        set
        {
            if (newValue.rangeOfCharacter(from: CharacterSet.decimalDigits) != nil){
                print("please enter valid name")
            }
            else
            {
                self.first_name = newValue
            }
        }
    }
}

let person1 = person.init()
person1.first_name = "rahul"

but this gives me error but when I do this example

import Foundation

class person
{
    var name = ""
    var first_name:String
    {
        get
        {
            return name
        }
        set
        {
            if (newValue.rangeOfCharacter(from: CharacterSet.decimalDigits) != nil){
                print("please enter valid name")
            }
            else
            {
                name = newValue
            }
        }
    }
}

let person1 = person.init()
person1.first_name = "rahul"
print(person1.first_name)

it runs and gives me output so my question is if I am using getter and setter then why I can't get or set the variable it self like I have done in above example so can any one explains me what is going on here

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
Devil Decoder
  • 966
  • 1
  • 10
  • 26
  • "but this gives me error but when I do this example" what error? – Larme Sep 28 '17 at 17:37
  • In your first example you have a *computed property* with a getter and a setter which *call themselves recursively* ... – Martin R Sep 28 '17 at 17:42
  • You should use struct instead of class and just create a fallible initializer. `struct Person { let name: String ; init?(name: String) { guard name.rangeOfCharacter(from: .decimalDigits) == nil else { return nil } ; self.name = name } }` – Leo Dabus Sep 28 '17 at 18:13
  • So when initialising your Person object `if let person = Person(name: "Rahul GUsai") { print(person.name) // "Rahul GUsai\n" } else { print("please enter valid name") }` – Leo Dabus Sep 28 '17 at 18:15
  • You can also add some computed properties to your Person struct to add functionality like extracting the familyName or givename from the person's name `extension Person { var personNameComponents: PersonNameComponents? { return PersonNameComponentsFormatter().personNameComponents(from: name) } var givenName: String? { return personNameComponents?.givenName } var familyName: String? { return personNameComponents?.familyName } }` – Leo Dabus Sep 28 '17 at 18:18
  • `if let person = Person(name: "Rahul GUsai") { print(person.familyName) // "GUsai\n" print(person.givenName) // "Rahul\n" } else { print("please enter valid name") }` – Leo Dabus Sep 28 '17 at 18:19

1 Answers1

0

Okay, suppose I'm setting the first_name property. So I call its setter. The setter makes sure the string is valid, and then calls:

self.first_name = newValue

This invokes first_name's setter. The string is still valid, so the setter calls:

self.first_name = newValue

This invokes first_name's setter. The string is still valid, so the setter calls:

self.first_name = newValue

and the cycle continues

By now you see the problem. This will go on forever until the program crashes due to too much recursion; you can't have the getter and setter call themselves like this. Instead, make a separate private var _first_name property, and have first_name's getter and setter access that.

Malik
  • 3,763
  • 1
  • 22
  • 35
Charles Srstka
  • 16,665
  • 3
  • 34
  • 60