It's interesting to see that we can now declare return values that are protocols with associated types.
The following throws an error and I don't understand the error.
protocol Plant: Equatable {
var maintenance: String { get }
}
struct Rose: Plant {
let height: Float // inches
let maintenance = "Water once a day."
}
struct Orchid: Plant {
let height: Float // inches
let maintenance = "Water once a month."
}
func makePlant1() -> some Plant {
Rose(height: 4)
}
func makePlant2() -> some Plant {
Orchid(height: 8)
}
let plant1: some Plant = makePlant1()
let plant2: some Plant = makePlant2()
func asdf() {
let condition: Bool = (plant1 == plant2) // error: ambiguous without more context
print(condition)
}
When you declare a function to return some Plant
then the compiler will look at the content of the function to see what real type is returned and in your example you are returning different types, Rose
and Orchid
.
This breaks the requirement from Equatable
that Self
must be the same, that you use some
doesn't mean that this requirement disappears.
The error message you get is a bit confusing but if you change it to
print(plant1 == plant2)
the error is more informative
Cannot convert value of type 'some Plant' (result of 'makePlant2()') to expected argument type 'some Plant' (result of 'makePlant1')
To be able to use ==
here you need to use objects created by the same function
func makePlant1(_ value: Float) -> some Plant {
Rose(height: value)
}
let plant1 = makePlant1(4)
let plant2 = makePlant1(4)
let plant3 = makePlant1(6)
print(plant1 == plant2) // true
print(plant1 == plant3) // false
Here is an informative article on the topic from hackingwithswift.com