Swift protocol mechaism

kindly anyone helps to explain the output "1,2,0,0" when expected is "1,2,-1,3"
following code produce output of
[1, 2, -1, 3]

[1, 2, 0, 0]

test2.BaseStagingConfig().a = 0

test2.StagingConfig().a = 3

Code in playground:

protocol Config {
var a: Int { get }
}
extension Config {
var a: Int { return 0 }
}

struct test1 {
class BaseConfig: Config {
var a: Int { return -1 }
}

class BaseDevConfig: BaseConfig {
    override var a: Int { return 1 }
}
class DevConfig: BaseDevConfig {
    override var a: Int { return 2 }
}
class BaseStagingConfig: BaseConfig {
    
}
class StagingConfig: BaseStagingConfig {
    override var a: Int { return 3 }
}

}

//current code : static dispatch?!?
struct test2 {
class BaseDevConfig: Config {
var a: Int { return 1 }
}
class DevConfig: BaseDevConfig {
override var a: Int { return 2 }
}
class BaseStagingConfig: Config {

}
class StagingConfig: BaseStagingConfig {
    var a: Int { return 3 }
}

}

let configs1: [Config] = [test1.BaseDevConfig(),
test1.DevConfig(),
test1.BaseStagingConfig(),
test1.StagingConfig()]
print("(configs1.map { $0.a })")

let configs2: [Config] = [
test2.BaseDevConfig(),
test2.DevConfig(),
test2.BaseStagingConfig(),
test2.StagingConfig()]
print("(configs2.map { $0.a })")
print("test2.BaseStagingConfig().a = (test2.BaseStagingConfig().a)")
print("test2.StagingConfig().a = (test2.StagingConfig().a)")

This is SR-103: a protocol's requirements are not re-checked for subclasses, so if the original class that adopts the protocol doesn't provide its own method to satisfy a requirement, subclasses can't override it. We'd rather have the behavior you expected (dynamic dispatch in both cases), but that'd potentially be a source-breaking change, since the subclass ought to use override to do it, and it's unclear how it would work with protocols adopted in extensions.

1 Like

I just want to say that this topic being fresh to my mind probably saved me a couple hours in debugging today. It'd be nice if there was at least a warning in a situation like this so you're put on the right path.