Usage of self. and .self?

I'm never really aware of when to use .self and rely on the computer to prompt me, but am confused as to what the difference is between self. and .self?

Many thanks.

self. is the prefix for accessing an instance property. it’s optional (but highly recommended) so long as the member name isn’t being shadowed in the current scope. self. also has a type-level variant, Self., which refers to the dynamic type of an instance.

.self is a syntactical annotation to distinguish references to a metatype entity from collections of themselves:

let foo = [Int.self] // inferred type: Array<Int.Type>
let bar = [Int].self // inferred type: Array<Int>.Type
let baz = [Int]      // not allowed, ambiguous
2 Likes

I've tried looking up what you wrote, but I don't understand what your saying?

There are two separate things here.

  1. Most of the time, self refers to the instance performing the method. This example gives an integer the ability to report its square. In the third line the integer multiplies itself times itself.

    extension Int {
        var squared: Int {
            return self * self
        }
    }
    

    The squared property can be called from somewhere else:

    let x = 3.squared
    // x is 9
    

    And in the same way, it can be called on itself. In the third line it asks itself for its square and then multiplies that by itself again.

    extension Int {
        var cubed: Int {
            return self.squared * self
        }
    }
    

    Since .squared can called on any integer, it can be called on 3 by doing 3.squared. Or some integer can call call it on itself: self.squared. That is where your “self.” is coming from, and the dot is really more related to whatever follows it.

  2. When .self follows a type name, it makes the reference refer not to any specific instance, but to the type’s abstract definition. In the third line of the following example, it asks the decoder to decode something as an Int. It wouldn’t make sense to ask it to decode a specific instance like 123, because then it would already be known. So instead it asks it to decode whatever number is there, but to generate it using the Int type (as opposed to some other type such as a Double). Hence it passes the abstract Int type definition itself.

    struct Thing {
        init(from decoder: Decoder) throws {
            let x = try decoder.decode(Int.self, forKey: "rawValue")
        }
    }
    

    This is what is going on every time you see “.self”, and it will only ever occur following the name of a type.