generics delegates swift3

generics - Existentials generalizados rápidos



delegates swift3 (1)

¿Hay alguna propuesta o discusión actualmente presente sobre la introducción de los Existenciales Generalizados en Swift? ¿Cuáles son los planes? Si no, ¿cómo puedo participar y afectar esto?

Es una característica comúnmente solicitada, y ya había un esfuerzo de diseño preliminar en la evolución rápida. Pero en este momento, el equipo central y la comunidad se están enfocando en las características que afectan la estabilidad de ABI, o lo que Lattner define como "Swift 4 Phase 1".

Definitivamente escucharías más sobre eso cuando comience la Fase 2. Dada su popularidad, se espera que sea parte de Swift 4.

Si Swift fue diseñado de esa manera (con tipos asociados, pero sin existenciales generalizados), tal vez implique algún cambio arquitectónico. ¿Con qué se espera que reemplace el patrón de delegación?

Puede usar envoltorios borrados por tipo como una solución transitiva. En general, explota el despacho dinámico y la herencia de las clases para borrar el tipo.

protocol Fancy { associatedtype Value var value: Value } struct FancyMatter<Value> { let value: Value } class AnyFancyBoxBase<P: FancyProtocol>: AnyFancyBox<P.Value> { let base: P override var value: P.Value { return base.value } init(_ base: P) { self.base = base } } class AnyFancyBox<Value> { var value: Value { fatalError() } } var box: AnyFancyBox<Int> = AnyFancyBoxBase(FancyMatter(1))

Puede ver cómo la Biblioteca estándar implementa envoltorios borrados por tipo .

Dejando a un lado la introducción redundante, quiero tener algo como esto:

let collection : Any<Sequence where .Iterator.Element == String> = ...

o

let collection : Sequence<where .Iterator.Element == String> = ...

Esto se conoce como "existenciales generalizados" en el Manifiesto de Genéricos de Apple . (Creo) Realmente necesito esto para una serie de casos de uso y esto:

el protocolo ''P'' solo se puede usar como una restricción genérica porque tiene requisitos propios o de tipo asociado.

hace que "el primer Lenguaje Orientado a Protocolo" sea engorroso para que lo entienda. La falta de esto me hace luchar contra el sistema de tipos de Swift y crear clases adversas genéricas "abstractas" donde debería haber un protocolo con tipo associatedtype .

Aquí hay un ejemplo, que me golpeó más, delegar para una clase genérica:

protocol GenericClassDelegate : class { associatedtype ItemType func didDoThat(who : GenericClass<ItemType>) } class GenericClass<T> { weak var delegate : GenericClassDelegate<where .ItemType == T>? // can''t do that func notify() { delegate?.didDoThat(who: self) } }

Aunque puedo describir el protocolo GenericClassDelegate , I (actualmente en Swift 3) no puedo tener una variable o constante de ese tipo (o cualquier tipo que cumpla con las restricciones).

No confunda esta pregunta con Cómo usar el protocolo genérico como un tipo de variable o el protocolo de delegado Swift para la clase genérica , ya que mis preguntas son:

  1. ¿Hay alguna propuesta o discusión actualmente presente sobre la introducción de los Existenciales Generalizados en Swift? ¿Cuáles son los planes? Si no, ¿cómo puedo participar y afectar esto?
  2. Si Swift fue diseñado de esa manera (con tipos asociados, pero sin existenciales generalizados), tal vez implique algún cambio arquitectónico. ¿Con qué se espera que reemplace el patrón de delegación?

PD: No sugiera los thunk con borrado de tipo cuando capture la función del delegado en un cierre, eso es tan erróneo y engañoso, incluso lo llamaría una muleta.

Accidentalmente encontré otra solución, pero no estoy satisfecho con ella por completo:

protocol GenericClassDelegate : class { associatedtype ItemType func didDoThat(who : GenericClass<ItemType, Self>) } class GenericClass<T, Delegate : GenericClassDelegate> where Delegate.ItemType == T { weak var delegate : Delegate? func notify() { delegate?.didDoThat(who: self) } init(_ delegate : Delegate?) { self.delegate = delegate } } // Delegates must be final classes, otherwise it does not compile // because I used Self in GenericClassDelegate final class GenericClassDelegateImp<T> : GenericClassDelegate { typealias ItemType = T func didDoThat(who: GenericClass<T, GenericClassDelegateImp>) { print(who) } } // Usage: var delegate = GenericClassDelegateImp<Int>() var genericClass = GenericClass<Int, GenericClassDelegateImp<Int>>(delegate)