I am teaching myself Swift and I have come across a problem that I do not quite understand. I am using the official Swift manual. In the manual there is a protocol named Shape
that has one requirement:
protocol Shape {
func draw() -> String
}
There is a struct called Triangle
which conforms to Shape
, from which we will create a variable called smallTriangle
:
struct Triangle: Shape {
var size: Int
func draw() -> String {
var result = [String]()
for length in 1...size {
result.append(String(repeating: "*", count: length))
}
return result.joined(separator: "\n")
}
}
let smallTriangle = Triangle(size: 3)
There is a generic struct named FlippedShape
that conforms to Shape
that accepts a generic parameter T
that also conforms to Shape
. The struct flips any shape that is passed to it:
struct FlippedShape<T: Shape>: Shape {
var shape: T
func draw() -> String {
let lines = shape.draw().split(separator: "\n")
return lines.reversed().joined(separator: "\n")
}
}
There is a generic function called protoFlip
which has a generic parameter T
that conforms to Shape
and has a return type of Shape
, an instance of FlippedShape
to be specific:
func protoFlip<T: Shape>(_ shape: T) -> Shape {
return FlippedShape(shape: shape)
}
An attempt to pass small triangle to this function and nest it results in an error:
protoFlip(protoFlip(smallTriangle))
The manual says that it is because:
"The result of flipping a triangle is a value of type Shape, and the
protoFlip(_:)
function takes an argument of some type that conforms to the Shape protocol. However, a value of a protocol type doesn’t conform to that protocol; the value returned byprotoFlip(_:)
doesn’t conform to Shape. This means code likeprotoFlip(protoFlip(smallTriange))
that applies multiple transformations is invalid because the flipped shape isn’t a valid argument toprotoFlip(_:)
."
I can't say I understand why this is so. The protoFlip
function accepts a generic parameter of type Shape
, and returns an instance that conforms to Shape
, so why exactly would that instance that is returned be considered an invalid argument to protoFlip
? I especially didn't understand the phrase "However, a value of a protocol type doesn’t conform to that protocol". What does this mean?