I am trying to switch from Java to Swift and improve my programming skills in this language.
However, I have some difficulties understanding how generics works in Swift after a study of:
https://docs.swift.org/swift-book/LanguageGuide/Generics.html
I have started to write a genetic algorithm by writing some protocols.
protocol Point : Equatable {
var identifier: String { get }
var x: Double { get }
var y: Double { get }
func distance<P : Point>(to point: P) -> Double
}
protocol Individual {
associatedtype P : Point
var fitness: Double { get }
var chromosomes: [P] { get }
}
and now I want to make a struct which conforms to the Individual protocol.
The only try that compiles is
struct Route : Individual {
typealias P = City;
var fitness: Double { 0.0 }
var chromosomes: [City]
}
However, I want to make Route as much as generic, therefore I don't want to tell that it uses City as implementation of Point. I want that Route knows that it works on array of objects which conforms to Point protocol.
I'd appreciate your help.
Thank you in advance.
First of all, I'd suggest adding a Self
requirement on the distance(to:)
method. Self
just tells the compiler that the paremeter is the same type as the conforming type.
protocol Point : Equatable {
var identifier: String { get }
var x: Double { get }
var y: Double { get }
func distance(to point: Self) -> Double
}
So, in your City
struct point
must also be of type City
.
struct City: Point {
var identifier: String
var x: Double
var y: Double
func distance(to point: City) -> Double {
return .zero
}
}
You can make your Route
struct more flexible by adding a generic parameter that also satisfies the associated type requirement imposed by the Individual
protocol.
struct Route<P: Point>: Individual {
var fitness: Double { 0.0 }
var chromosomes: [P]
}
To instantiate a Route
:
var cityRoute = Route<City>(chromosomes: [])