Подтвердить что ты не робот

Требовать тип и протокол для параметра метода

Я играю с Swift и спотыкаюсь о следующей проблеме: учитывая, что у меня есть предопределенный класс Animal:

//Predefined classes
class Animal {
    var height: Float = 0.0
}

Теперь я напишу класс Zoo с конструктором, принимающим животных. Но Zoo хочет, чтобы каждое животное имело имя и, следовательно, определяло протокол Namable.

protocol Namable {
    var name: String {get}
}

class Zoo {
    var animals: Animal[] = [];
}

Как вы напишете метод addAnimal, который требует, чтобы объект, передаваемый как параметр, был как Animal, так и соответствовать протоколу Namable? И как вы объявляете это для массива animals?

    func addAnimal:(animal: ????) { ... }

В Objective-C я бы написал что-то вроде этого

    - (void)addAnimal:(Animal<Namable>*)animal {...}
4b9b3361

Ответ 1

Вы можете использовать общий код с предложением where с несколькими условиями.

func addAnimal<T: Animal where T: Nameable>(animal: T) { ... }

Поправка. Вероятно, вы должны сделать весь класс таким общим, чтобы правильно ввести массив

class Zoo<T: Animal where T: Nameable> {
    var animals : T[] = []
    func addAnimal(a: T) {
        ...
    }
}

Ответ 2

Для меня это выглядит скорее проблемой архитектуры:

Nameable является странным как протокол. Логически каждое животное имеет возможность быть названным так Animal должно всегда соответствовать Nameable

Было бы гораздо проще разрешить имена nil, когда животное не будет названо, вместо того, чтобы иметь животных, которые могут иметь имя и животных, которые не могут.

Затем вы можете назначать имена в Zoo просто assert.

Ответ 3

<> находится в Objective-C: соответствует протоколу

<> находится в Swift для дженериков

Вы можете сделать больше с ключевым словом where

Используйте , где, после имени типа, чтобы указать список требований, например, чтобы потребовать, чтобы тип выполнял протокол, чтобы требовать, чтобы два типа были одинаковыми или требовали, чтобы класс имеют специальный суперкласс.

Отрывок из: Apple Inc. "Быстрый язык программирования". iBooks.

Ответ 4

версия Swift 3

В Swift 3 структура немного изменилась. Вот почему вы получите предупреждение об устаревании старой структуры. Вот новый:

Для функций ожидаемые протоколы расположены после определения параметров функции. Пример:

func addAnimal<T: Animal>(animal: T) where T: Nameable

Для перечислений или классов структура также изменилась

enum ZooEnum<T: Animal> where T: Nameable 

class Zoo<T: Animal> where T: Nameable