I have the following structs that represent a point or a line:
public struct Point{
let x : Double
let y : Double
init (x : Double, y : Double)
{
self.x = x
self.y = y
}
}
extension Point : Equatable{}
public func ==(lhs: Point, rhs: Point) -> Bool
{
return lhs.x == rhs.x && lhs.y == rhs.y
}
And
public struct Line {
let points : [Point]
init(points : [Point])
{
self.points = points
}
}
extension Line : Equatable {}
public func ==(lhs: Line, rhs: Line) -> Bool
{
return lhs.points == rhs.points
}
I want to be able to have a Shape protocol or struct that I can use to have Points and Lines and then I can compare between them. I tried to that with conforming protocol Shape but Swift compiler gives me an error when I want to compare a point with a line even though they are Shapes.
Do I have to move from struct to classes?
I think I may have to use generics but don't know exactly how to solve this issue.
Thanks in advance for any guidance.
Edit1:
My approach to Shape protocol was really just trying stuff but nothing worked. I tried the following:
protocol MapShape : Equatable
{
func == (lhs: MapShape, rhs: MapShape ) -> Bool
}
I also changed the code for the Equatable extension for lines given the suggestion
This topic is covered in the WWDC 2015 session video Protocol-Oriented Programming in Swift, and here is my attempt to apply that to your situation:
You define a protocol Shape
and a protocol extension method
isEqualTo:
:
protocol Shape {
func isEqualTo(other: Shape) -> Bool
}
extension Shape where Self : Equatable {
func isEqualTo(other: Shape) -> Bool {
if let o = other as? Self { return self == o }
return false
}
}
isEqualTo:
checks if the other element is of the same type (and compares them with ==
in that case), and returns false
if they
are of different type.
All types which are Equatable
automatically conform to Shape
,
so that we can just set
extension Point : Shape { }
extension Line : Shape { }
(Of course you can add other methods to Shape
which should be
implemented by all shape types.)
Now we can define ==
for shapes as
func ==(lhs: Shape, rhs: Shape) -> Bool {
return lhs.isEqualTo(rhs)
}
and voilà, points and lines can be compared:
let p1 = Point(x: 1, y: 2)
let p2 = Point(x: 1, y: 3)
let l1 = Line(points: [p1, p2])
let l2 = Line(points: [p1, p2])
print(p1 == p2) // false
print(p1 == l1) // false
print(l1 == l2) // true
Remark: You have ==
for the Shape
type now, but I haven't figured out yet to how make Shape
conform to Equatable
. Perhaps someone
else can solve that part (if it is possible).