.self after struct type in Swift

Viewed 1999

I’m confused by a line of code found in the Metal example where the memory pointer is bound to a type.

uniforms = UnsafeMutableRawPointer(uniformBuffer.contents()).bindMemory(to: Uniforms.self, capacity: 1)

My confusion is the .self after the Uniforms type. Uniforms is a struct defined in an Objective-C file and the code wont run without .self being in the call. Why is that necessary?

2 Answers

The .self returns the metatype instance for the corresponding type. Think of it as a typesafe type identifier (e.g., way safer than using a string for that). You can then safely call the available initializers, static methods, static properties on such metatype instance.

For instance, you could store it in a variable as well:

let metatype: Uniforms.Type = Uniforms.self

and Uniforms.Type is the actual metatype (i.e., the type's type).

Metatype crash course. A very quick example to get a feel of how this meta stuff might be actually useful:

class Super {
    let id: Int
    required init(id: Int) { self.id = id }
}

class SubA: Super { ... }
class SubB: Super { ... }

let subclass: Super.Type = SubA.self

and then, later on, use subclass to create an instance without hardcoding the actual subclass type name:

let obj = subclass.init(id: 123) // new SubA instance.

In Swift, .self could be used on a type to extract its meta type or on an instance of a type. Example, use .self to get the meta type and pass it to the API:

self.tableView.registerClass(
    UITableViewCell.self, forCellReuseIdentifier: "myUIViewCell")
Related