Tugulab Blog.

Why Swift protocol conforming values are treated as Value types by default?

Why the compiler decides to ignore the real type of something that conforms to a protocol?
author avatar


Let’s say you have a protocol, which only describes an interface. It does not restrict the conformance to only instance types (no : class).

protocol AlphaProtocol {
var message: String? { get set }

Why do the compiler treats the conforming value/object always as a Value type?

If we modify alphaValue property, the compile will ignore the actual type of alphaValue. It will always treat the property as a value type (e.g. struct). So it will create a copy of alphaValue with a different message, then it will replace the old copy with the new one.

If you restrict the AlphaProtocol to classes only, then alphaValue will be correctly be treated as an Instance type. So if you now update the message in AlphaObject, it will just update the message in the current instance.

protocol AlphaProtocol: class {
var message: String? { get set }

This behaviour has been particularly hard to understand, since it’s not intuitive at all.

But the real question is: is this behaviour correct? Is it intended to work that way? If so, why?