2014-12-16 5 views
9

Self может быть использован в качестве возвращаемого типа метода:Использование Я как универсального типа

func doSomething() -> Self {} 

ли это как-то можно использовать Self в качестве общего типа, как это?

func doSomething() -> Wrapper<Self> {} 

Пример

Было бы хорошо, если бы я мог создать подкласс ChristmasPresent и пусть он имеет wrapped функцию, которая возвращает WrappedPresent с общей установкой на то, что подкласс был.

class ChristmasPresent { 
    func wrapped() -> WrappedPresent<Self> { 
     return WrappedPresent(present: self) 
    } 
} 

class WrappedPresent<T: ChristmasPresent> { 
    var present: T 

    init(present: T) { 
     self.present = present 
    } 
} 

class ToyCar: ChristmasPresent {} 

let wrappedToyCar = ToyCar().wrapped() // Inferred to be: WrappedPresent<ToyCar> 
+0

Что бы это ограничение представляло? Где зарегистрировано это общее ограничение? Как объявляется Wrapper? Если это 'Wrapper ', мы можем вернуть 'Wrapper ', возможно. – cmyr

+0

Есть ли причина, по которой вы не знаете тип «Я» в то время? Может быть, я просто недостаточно серьезно. Вы всегда можете заменить «Я» на фактическое имя класса – bjtitus

+0

Я добавил пример :). – Rengers

ответ

19

Самого неприятный парадокс Swift это: «Swift предпочитает методы, но функция Свифта является более мощной.» Команда Свифт знает это, и когда-нибудь я уверен, что у нас будут мощные методы. Но сегодня не тот день. Есть много вещей, которые вы хотели бы выразить в методах, которые вы не можете. Однако все, что вам нужно, можно легко выполнить с помощью функций.

class ChristmasPresent {} 

struct WrappedPresent<T: ChristmasPresent> { 
    let present: T 
} 

func wrap<T:ChristmasPresent>(present: T) -> WrappedPresent<T> { 
    return WrappedPresent(present: present); 
} 

class ToyCar: ChristmasPresent {} 

let wrappedToyCar = wrap(ToyCar()) // Inferred to be: WrappedPresent<ToyCar> 

Обратите внимание, что если ваш код сделал компиляции, вы все еще можете быть очень удивлены результатом. Swift custom types are not covariant, поэтому WrappedPresent<ToyCar> не является подтипом WrappedPresent<ChristmasPresent>. Поэтому, если у вас был массив обернутых подарков, вы не могли бы поместить в него завернутый toycar. Это может привести к тому, что вы снова вернетесь к использованию только фиксированного типа (без параметров) WrappedPresent, сделав вопрос спорным. Дженерики и классы не всегда смешиваются, как вы можете себе представить в Swift.

Если у вас есть практический пример проблемы, с которой вы хотели бы решить, тогда я рекомендую поднять ее на форумах разработчиков. Команда Swift очень отзывчива.

+1

Ах, конечно, мне никогда не приходило в голову, что это разрешимо с функциями! Все еще мыслить в Objective-C мышлении слишком много :). – Rengers

Смежные вопросы