In some definition of protocol, we may notice there is capital Self used as type:

protocol IntervalType {
    //...

    /// Return `rhs` clamped to `self`.  The bounds of the result, even
    /// if it is empty, are always within the bounds of `self`
    func clamp(intervalToClamp: Self) -> Self

    //...
}

This IntervalType protocol defines a method, which accepts itself as an argument, and returns the same type.

Since there is no context with a protocol, and any types in Swift could conform to a protocol, we do not have any idea about what type will conform to it when declaring the protocol. So, when working in a protocol, Self is an abstract type here, and is used to represent the real type that conforms to current protocol.

It is not so difficult in concept for Self, but it is not easy to implement it either. Let's say we have a Copyable protocol, in which there is a method to return a copy of the instance. At the beginning, we may consider this kind of definition:

protocol Copyable {
    func copy() -> Self
}

It's neat. The return value should not be changed since it is a copy, so Self is used here. Let's try to write a MyClass to conform it now:

class MyClass: Copyable {

    var num = 1

    func copy() -> Self {
        // TODO: We need add some thing here
        // return
    }
}

At first, we might write this:

This is wrong code

func copy() -> Self {
    let result = MyClass()
    result.num = num
    return result
}

This cannot compile. It requires an abstract Self, but the return value is an instance of a real type MyClass in fact. By changing the Self to MyClass we could make the declaration match the return value, but it also makes the signature of this method different from the one in protocol, which will fail in compiling as well.

To solve this dilemma, we need an init method which is not related to context (type of MyClass here), but could represent current type. Hope you can remember the dynamicType we mentioned in the previous "Get type of instance". Here we use it to create an instance. By doing so, MyClass and its subclasses could return a proper instance to meet the demand of Self:

This is wrong code

func copy() -> Self {
    let result = self.dynamicType()
    result.num = num
    return result
}

However, even by doing this, we cannot get it compile. The compiler will kindly give us a tip: if we want to create a Self type instance, we need to add required keyword to the init method. That makes sense, we should make a promise that all subclasses should be able to response to this init method. There is another solution for it, we could add the final keyword before the declaration of our class. This will make the type to be final and cannot be inherited from anymore. In this example, we choose the "require" way. Just adding an empty required init would do the trick. At last, MyClass is:

class MyClass: Copyable {

    var num = 1

    func copy() -> Self {
        let result = self.dynamicType()
        result.num = num
        return result
    }

    required init() {

    }
}

Time for testing the behavior:

let object = MyClass()
object.num = 100

let newObject = object.copy()
object.num = 1

print(object.num)     // 1
print(newObject.num)  // 100

Cool. And for subclass of MyClass, copy() will return a copied instance of that subclass as well.

Self is also used in class method, which has a very similar rule. The core concept is how to ensure that the subclasses also return the correct type.