Swift, протоколы и обобщения в алгоритме Geneti c - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь перейти с Java на Swift и улучшить свои навыки программирования на этом языке.

Однако у меня возникают некоторые трудности с пониманием того, как дженерики работают в Swift после изучения:

https://docs.swift.org/swift-book/LanguageGuide/Generics.html

Я начал писать алгоритм geneti c, написав несколько протоколов.

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 }
}

и теперь я хочу создать структуру который соответствует Индивидуальному протоколу.

Единственная попытка компилирования:

struct Route : Individual {
    typealias P = City;
    var fitness: Double { 0.0 }
    var chromosomes: [City]
}

Однако я хочу сделать Route столько же, сколько generi c, поэтому я не хочу скажи что он использует City как реализацию Point. Я хочу, чтобы Route знал, что он работает с массивом объектов, который соответствует протоколу Point.

Буду признателен за вашу помощь.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

Вы можете создать массив класса, который реализует указанный протокол c, поэтому, например, в этом случае у вас будет:

 struct Route: Individual {
    typealias P = City;
    var fitness: Double { 0.0 }
    var chromosomes: [Point]
}

, и вы сможете вызывать все методы протокола.

0 голосов
/ 02 мая 2020

Прежде всего, я бы предложил добавить требование Self к методу distance(to:). Self просто сообщает компилятору, что тип paremeter совпадает с типом соответствия.

protocol Point : Equatable {
    var identifier: String { get }
    var x: Double { get }
    var y: Double { get }
    func distance(to point: Self) -> Double
}

Итак, в вашей City struct point также должен быть тип City.

struct City: Point {
    var identifier: String
    var x: Double
    var y: Double

    func distance(to point: City) -> Double {
        return .zero
    }
}

Вы можете сделать вашу структуру Route более гибкой, добавив универсальный параметр c, который также удовлетворяет требованию связанного типа, установленному протоколом Individual.

struct Route<P: Point>: Individual {
    var fitness: Double { 0.0 }
    var chromosomes: [P]
}

Для создания экземпляра Route:

var cityRoute = Route<City>(chromosomes: [])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...