Requiring reference semantics

Protocols can be adopted by both value types (structs and enums) and reference types (classes), so you might wonder if protocols have reference or value semantics.

The truth is... it depends! If you have an instance of a class or struct assigned to a variable of a protocol type, it will express value or reference semantics that match the type it was defined as.

To illustrate, take the simple example of a Named protocol below, implemented as a struct and a class:

protocol Named {

var name: String { get set }

}

class ClassyName: Named { var name: String init(name: String) {

self.name = name

}

}

struct StructyName: Named { var name: String

}

If you were to assign a Named variable an instance of a reference type, you would see the behavior of reference semantics:

var named: Named = ClassyName(name: "Classy") var copy = named

named.name = "Still Classy" named.name // Still Classy copy.name // Still Classy

Likewise, if you assign an instance of a value type, you would see the behavior of value semantics:

named = StructyName(name: "Structy") copy = named

named.name = "Still Structy?" named.name // Still Structy? copy.name // Structy

The situation isn’t always this clear; you’ll notice that most of the time Swift will favor value semantics over reference semantics. If you’re designing a protocol to be adopted exclusively by classes, it’s best to request that Swift uses reference semantics when using this protocol as a type.

protocol Named: class {

var name: String { get set }

}

By using the class constraint above, you indicate that only classes may adopt this protocol. This makes it clear that Swift should use reference semantics.

results matching ""

    No results matching ""