2015-08-27 3 views
0

В следующем примере должны быть созданы конкретные объекты для абстрактных протоколов.Функция вызова с общим протоколом как тип возврата

class ClassA<T: FloatingPointType> {} 

protocol ProtocolA 
{ 
    typealias T: FloatingPointType 
    var value : ClassA<T>? { get set } 
} 

class ClassImplProtocolA<T: FloatingPointType> : ProtocolA 
{ 
    var value : ClassA<T>? { 
     get { 
      return nil 
     } 
     set { 
     } 
    } 
} 

class Factory 
{ 
    class func createProtocol<PA: ProtocolA where PA.T: FloatingPointType>() -> PA 
    { 
     let concreteObject = ClassImplProtocolA<PA.T>() 
     let abstractObject = concreteObject as? PA 
     return abstractObject! 
    } 
} 

Теперь два вопроса: Можно ли избежать as? PA? и как выглядит синтаксис для вызова Factory.createProtocol<...>()?

Или как мне обойти это? Все, что я хочу, является объектом абстрактного типа PrtocolA<FloatingPointType> без экспозиции ClassImplProtocolA.

ответ

1

Во-первых, вы не можете избежать as? PA, так как возвращение типа определяется умозаключения типа, как это:

let prot: ClassImplProtocolA<Double> = Factory.createProtocol() 
let prot = Factory.createProtocol() as ClassImplProtocolA<Double> 

Другой проблемой в данном случае является то, что вы не можете использовать FloatingPointType в качестве универсального типа (имеет Self требования), и вы должен использовать тот, который соответствует этому протоколу (например, Double и Float).

В стандартной библиотеке Свифта они используют AnySequence, AnyGenerator ... (общие структуры) для того, чтобы иметь абстрактный тип протокола, который имеет Self требования. К сожалению, вы не можете сделать тип AnyProtocolA<FloatingPointType>, потому что сам общий тип имеет требования Self.

+0

Спасибо, что помогает понять. Таким образом, я могу создать фонд (например, 'createProtocol' здесь) в swift, который невозможно вызвать? – V1ru8

+1

@ V1ru8 Этот 'func' может быть вызван, как я показал в двух примерах. Но почему вы делаете «func», что невозможно назвать? Просто не реализуйте его. – Qbyte

+1

Я запутался, но нормально, я понял это сейчас. Все это выглядит довольно уродливо, так как невозможно получить два уровня абстрактных дженериков. Вызов 'createProtocol' без раскрытия' ClassImplProtocolA' на самом деле невозможен. Использование 'AnyGenerator' рода убивает всю идею дженериков и не помогает сделать код более читаемым. – V1ru8

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