Функция Swift Protocol: возврат того же типа соответствующего класса

Я хочу знать, можно ли сделать что-то похожее на java (или c ++) в Swift:

У меня есть протокол:

protocol Prot1 {
   func returnMyself() -> Prot1
}

А класс соответствует протоколу Prot1. Могу ли я сделать так, чтобы возвращаемый тип функции returnMyself() был того же типа, что и класс, как показано ниже?

class MyClass: Prot1 {
   public func returnMyself() -> MyClass {
      return self
   }
}

Является ли это возможным?


person 4bottiglie    schedule 14.06.2016    source источник


Ответы (2)


Просто используйте Self в своем протоколе

protocol Prot1 {
   func returnMyself() -> Prot1
}

Вот пример

protocol Animal {
    func mySelf() -> Self
}

class Feline: Animal {
    func mySelf() -> Self {
        return self
    }
}

class Cat: Feline { }

Feline().mySelf() // Feline
Cat().mySelf() // Cat

О расширениях протокола

Вы также можете использовать Self внутри такого расширения протокола

protocol Animal {}

extension Animal {
    func mySelf() -> Self {
        return self
    }
}

Теперь классу просто нужно соответствовать Animal, как это

class Feline: Animal { }
class Cat: Feline { }
class Dog: Animal {}

и автоматически получает метод

Feline().mySelf() // Feline
Cat().mySelf() // Cat
Dog().mySelf() // Dog

Обновлять

protocol ReadableInterval { }

class Interval: ReadableInterval { }

protocol ReadableEvent {
    associatedtype IntervalType: ReadableInterval
    func getInterval() -> IntervalType
}

class Event: ReadableEvent {
    typealias IntervalType = Interval
    func getInterval() -> Interval {
        return Interval()
    }
}
person Luca Angeletti    schedule 14.06.2016
comment
Хорошо, я бы использовал для этого связанный тип. Это намного приятнее. - person Alexander; 14.06.2016
comment
@AMomchilov: Спасибо! - person Luca Angeletti; 14.06.2016
comment
Мне нравится этот подход, но это был пример специализации, в случае, если у меня MyClass2, ведьма также подтверждает Prot1, могу ли я специализировать член func returnMyself () - ›MyClass2 из MyClass? - person 4bottiglie; 14.06.2016
comment
@ 4bottiglie: Конечно! Вы также можете реализовать этот метод в MyClass2. Не забудьте добавить ключевое слово override и вернуть MyClass2. - person Luca Angeletti; 14.06.2016
comment
Я понимаю это, но мой вопрос был в том, есть ли способ реализовать: func returnMyself () - ›MyClass2 в MyClass, а не в MyClass2; не спрашивайте меня, зачем мне это нужно, это развеет мои сомнения в специализации. - person 4bottiglie; 14.06.2016
comment
@ 4bottiglie В коде вашего вопроса вы спросили, как вернуть MyClass из MyClass. Теперь вы хотите вернуть MyClass2 из MyClass? Итак, вы хотите объявить метод, который всегда возвращает MyClass2? - person Luca Angeletti; 14.06.2016
comment
Прошу прощения за первый вопрос. Я не думал, что есть много способов специализации возвращаемого типа (я пришел из java). Если у меня есть протокол (например, MyProt), у которого есть метод, который возвращает другой протокол (func getProt () - ›ProtR1). Допустим, MyClass подтверждает MyProt, а MyClassR подтверждает ProtR1. Могу ли я контролировать такой метод в MyClass, как: func getProt () - ›MyClassR? - person 4bottiglie; 14.06.2016
comment
@ 4bottiglie: что?!?! : D Дайте мне код Java, чтобы я мог понять, что вам нужно. - person Luca Angeletti; 14.06.2016
comment
@ 4bottiglie: дайте мне знать, решит ли обновленный раздел вашу проблему - person Luca Angeletti; 14.06.2016
comment
Я видел обновление, getInterval () из ReadableEvent должен возвращать ReadableInterval, а не Interval, потому что в реализациях ReadableEvent я хочу возвращать другие типы Interval, которые не являются необходимыми подклассами Interval - person 4bottiglie; 14.06.2016

person    schedule
comment
Мне нравится твой стиль; связанный тип T будет ограничен для подклассов Prot1, когда вы сделаете: typealias T = MyClass? Если нет, то это способ его ограничить? - person 4bottiglie; 14.06.2016
comment
как только вы сделаете typealias T = MyClass, он будет ограничен MyClass. Это означает, что подклассы также должны будут реализовывать func returnMyself() -> MyClass - person Daniel; 14.06.2016