UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Why use of self in initializer.

Forums > 100 Days of SwiftUI

Hello i dont get it why we use self in initialize of a struct (https://www.hackingwithswift.com/quick-start/beginners/how-to-create-custom-initializers) What name is equal to what name? There is only one constant name. Could anyone describe me this in other way or give some example?

I mean this part of code:

        self.name = name
        self.number = number

In that code I thought the name in init is the same name of a variable. Why do i need to specify its the same name:

struct Student {
    var name: String
    var bestFriend: String

    init(name: String, bestFriend: String) {
        print("Enrolling \(name) in class…")
        self.name = name
        self.bestFriend = bestFriend
    }
}

2      

Filip is confused by a common convention:

Hello i dont get it why we use self in initialize of a struct. What name is equal to what name? Could anyone describe me this in other way or give some example?

You are not alone! This convention of name = name confuses a lot of people!

// Create a box on your desk.
// This box holds two pieces of data, a name, and a bestFriend's name
struct Student {
    var name:       String    // Store a student's name
    var bestFriend: String    // Store a best friend's name

// When you create a new box, you have to provide two pieces of data.
// You must provide a new name, and a new bestFriend's name
    init(name: String, bestFriend: String) {  // <-- These are temporary until saved to the struct
        print("Enrolling \(name) in class…")
        self.name       = name        // <-- This is confusing!
        self.bestFriend = bestFriend  // <-- Also confusing
    }
}

One way to reduce this confusion is to NOT give them the same name.

// Create a box on your desk.
// This box holds two pieces of data, a name, and a bestFriend's name
struct Student {
    var name:       String    // Store a student's name
    var bestFriend: String    // Store a best friend's name

// When you create a new box, you have to provide two pieces of data.
// You must provide a new name, and a new bestFriend's name
// newStudent and newBestFriend ONLY belong to this initializer.
// name and bestFriend belong to the Struct. (aka "self")
    init(newStudent: String, newBestFriend: String) {
        print("Enrolling \(name) in class…")
        // Push the newStudent's name into the Struct's name variable.
        name       = newStudent     // <-- This is what you passed in when creating a NEW Student
        // Push the newBestFriend's name into the Struct's bestFriend variable.
        bestFriend = newBestFriend  // <-- Also passed in.
    }
}

So when you need to create a new student in your application you'd do this:

let newStudent = Student(newStudent: "Filip", newBestFriend = "twoStraws") // <-- create a new student

This eliminates the need to code self.name = name

2      

This code is defining a struct named Player. When you define a struct, you haven't created any instances of Player yet, you are just writing down what properties a player will have, and what functions it will be capable of preforming when you do create one. Then, we use the initializer to create them.

struct Player {
    let name: String
    let number: Int

    init(name: String, number: Int) {
        self.name = name
        self.number = number
    }
}

Now, imagine we create 3 separate players using the initializer with some code like this...

var david = Player(name: "David", number: 1)
var alice = Player(name: "Alice", number: 2)
var joey = Player(name: "Joey", number: 3)

When we were defining the struct itself, it had no way of knowing what we would name our players, or how to identify them individually, because they didn't exist yet. So, we use self.name and self.number instead. Self will basically point to whatever player is currently being created by the initializer. So, instead of trying to set the name property of the struct itself, we are only setting the name property of the Player that is currently being created by the initializer.

So, when we are creating Joey, it knows to only set Joey's name to be Joey, without changing the name of any other player that has previously been created. It will only set the name of the Player that is currently being created by the intializer to Joey.

2      

@piMu  

struct SuperHero { var nickname: String var powers: [String] init(nickname: String, superPowers: [String]) { self.nickname = nickname self.powers = superPowers } } let batman = SuperHero(nickname: "The Caped Crusader", superPowers: ["He's really rich"])

(this is one of your exercices/example)

Hi. So, if I understand it well, in line 6, the "self." is not mandatory (for superPowers<>powers...)? Thank you.

2      

struct SuperHero {
    var nickname: String
    var powers: [String]

    init(nickname: String, superPowers: [String]) {
        self.nickname = nickname
        powers = superPowers
    }
}

let batman = SuperHero(nickname: "The Caped Crusader", superPowers: ["He's really rich"])

Hi. So, if I understand it well, in line 6, the "self." is not mandatory (for superPowers<>powers...)? Thank you.

Correct.

When SuperHero is called in let batman = … it passes the parameters for the init.

In the structure there are two parameters named nickname, and you need to give some initial value to the internal nickname i.e. the one declared by var nickname: String. Also as there are two with the smae name it is necessary to distinguish between them. So the one with the self. is the internal one, whilst the one without the .self is the one coming form outsode as part of the init.

As powers != superPowers it is clear which one is which, as so .self is not strictly needed. It can be added for stylistic and style guidelines purposes, and to have some consistency in the layout, but adding or omitting it in this case will not affect the functionality.

2      

You have this struct and ask why you have self. It refers to the struct it-self not the value in the init

struct Student {
    var name: String
    var bestFriend: String

    init(name: String, bestFriend: String) {
        print("Enrolling \(name) in class…")
        self.name = name
        self.bestFriend = bestFriend
    }
}

so you could change it to this

struct Student {
    var name: String
    var bestFriend: String

    init(inputName: String, inputBestFriend: String) {
        print("Enrolling \(name) in class…")
        name = inputName
        bestFriend = inputBestFriend
    }
}

see no self need. However to save on thinking about new value name it tend to use the same name as the struct properties so the complier know that you not assign the same properties together.

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.