2016-06-06 3 views
0

Я пытаюсь получить код ниже работаю на детской площадке:SWIF общего типа наследование от другого универсального типа

public protocol SomeTypeProtocol { 
    associatedtype T 
    func convertTo<TNew:SomeTypeProtocol>()-> TNew 
} 

public class SomeClass<T>: SomeTypeProtocol{ 

    var item:T 
    public init(item:T) 
    { 
     self.item = item 
    } 
    public func convertTo<TNew:SomeTypeProtocol where TNew.T : T>()-> TNew 
    { 
     return SomeClass<TNew.T>(item: item as! TNew.T) 
    } 
} 

В принципе, у меня есть протокол с ассоциированным типом Т, и класс, соответствующий этим протокол с родовым типом T, и мне нужно реализовать функцию convertTo, которая просто преобразует тип класса T в другой тип TNew.T, который должен быть подклассом из T. . У меня это реализовано на других языках, таких как C# и Java, поэтому я не знаю, почему я не могу заставить его работать в Swift. Я получаю следующие ошибки:

1) error: type 'TNew.T' constrained to non-protocol type 'T' 
    public func convertTo<TNew:SomeTypeProtocol where TNew.T : T>()-> TNew 
2) error: cannot invoke initializer for type 'SomeClass<TNew.T>' with an argument list of type '(item: TNew.T)' 
     return SomeClass<TNew.T>(item: item as! TNew.T) 

3) note: expected an argument list of type '(item: T)' 
     return SomeClass<TNew.T>(item: item as! TNew.T) 

4)note: protocol requires nested type 'T' 
    associatedtype T 

Спасибо!

+0

Я не достаточно хорош с генериками, но у меня есть возможность ответить на ваш вопрос, но я хотел бы отметить, что быстрое соглашение о создании конвертеров заключается в создании расширений, которые определяют новый метод 'init', который принимает нужный ввод, который нужно преобразовать – Alexander

+0

Вы говорите, что статический тип 'TNew.T' должен быть подклассом' T' ... динамические типы одинаковы? (Или динамический тип 'TNew.T' суперкласса' T'?) В противном случае вы не сможете сделать это преобразование. – Hamish

ответ

0

TNew.T : T

Это где проблема лежит.

Двоеточие, :, используется для объявления ограничения соответствия, а не равенства. Вам нужно переписать это как TNew.T == T, если вы хотите приравнять два типа: TNew.T и T.

+0

Является ли равенство также указанием наследования? Я хочу, чтобы TNew.T был подклассом T, не равным T. Спасибо :) –

0

Я считаю, что ближайший вы можете получить что-то делать, как это так:

public func convertTo<TNew where TNew : T>()-> SomeClass<TNew> 
{ 
    return SomeClass<TNew>(item: item as! TNew) 
} 

Но я не верю, что вы не можете применять это время только подкласс, а не тот же класс.

Будьте осторожны, делая этот тип вещей с помощью дженериков. Если вам нужно постоянно изменять тип своего общего, вы можете рассмотреть возможность использования другого дизайна.

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