Hi.
I'm writing some code, and it works, but I'm not sure how much I can trust that it'll continue to work.
Say I have an object like a calculator (it's not...but for the sake of this problem it doesn't matter), however my calculator only handles addition.
class Calculator {
private(set) var total: Double = 0.0
}
I add some functions that allow basic types to be added to the total, like Int, Double...etc.
class Calculator {
private(set) var total: Double = 0.0
func add(_ value: Double) {
total += value
}
func add(_ value: Int) {
total += Double(value)
}
}
All is working fine, but now I want to add a protocol that allows other people to allow their types to be added to my calculator. So I do something like this:
protocol Addable {
func add(to calculator: inout Calculator)
}
class Calculator {
private(set) var total: Double = 0.0
func add(_ value: Double) {
total += value
}
func add(_ value: Int) {
total += Double(value)
}
func add(_ addable: Addable) {
addable.add(&self)
}
}
And types can conform to it like this:
struct MyAddable: Addable {
let someInt = 1
let someDouble = 2.0
func add(to calculator: inout Calculator) {
calculator.add(someInt)
calculator.add(someDouble)
}
}
So far, this works fine (as far as pseudo code), but let's say somebody wants to use Addable
as a type, for example this function:
struct MyObject {
var calculator = Calculator()
func add(_ addable: Addable) {
calculator.add(addable)
}
}
This will work, but as Int types, or Doubles don't conform to Addable
, you can't call add(1)
on MyObject
, so conformance to Addable
needs adding to Int
and Double
.
extension Int: Addable {
func add(to calculator: inout Calculator) {
calculator.add(self)
}
}
And this is where I'm getting confused. The signature on Calculator
for adding an integer is surely the same as the the version that takes an Addable
, but the implementation is quite different. Additionally, could it call itself recursively - for example could the Addable
implementation on Int
when attempting to call add(:)
on Calculator
, accidentally call the version that takes an Addable
, as Int
now conforms to this?
How are conflicts like this handled?
Does it work because MyObject is referring to an Addable
, and not to a specific type, whereas the implementation on Int
for Addable
is referring to the concrete type? If so, can I trust this will "just work"?
Thanks and apologies for the convoluted example.
-Matt