Tengo un Event de estructura que se inicializa con una hora y un valor.
El tipo de propiedad de value se decide en el momento en que se crea el evento. Puede ser una primitiva Int o Double .
¿Cómo debo implementar esto en Swift?
Quiero poder crear un nuevo objeto Event así:
let event = Event(time: Date.init(), value: EventValue<Double>(40.3467))Encontré esto pero no puedo descifrarlo.
He experimentado con tantas permutaciones de esto y lo mejor que puedo hacer es
struct Event { let time: Date var value: EventValue? // This line 'requires arguments in <...>' } struct EventValue <T> { let value: T? }Agregue un parámetro genérico a su estructura de Event también y luego use este tipo para el parámetro de EventValue
struct Event<T> { let time: Date var value: EventValue<T>? } luego simplemente inicialice EventValue sin especificar el tipo, ya que el compilador le permite pasar solo el valor correspondiente a la restricción de parámetro genérico. Y dado que su parámetro no tiene restricciones, es igual a Any , por lo que puede pasar cualquier tipo
let event = Event(time: Date.init(), value: EventValue(value: 40.3467))Dado que EventValue es genérico, no se puede usar directamente como el tipo de una propiedad. * Debe especificar directamente el parámetro de tipo, lo que le brinda un contenedor que siempre tiene una variedad particular de EventValue :
struct DoubleEvent { // Please pick a better name, though let time: Date var value: EventValue<Double>? }O haga que el contenedor sea genérico también:
struct Event<T> { let time: Date var value: EventValue<T>? } En cualquier caso, no tiene que proporcionar explícitamente el tipo al crear un Event : let event = Event(time: Date(), value: EventValue(value: 40.3467)) La inferencia de tipo lo completará cuando el Event en sí sea genérico.
(Aparte: tenga en cuenta que no tiene ninguna restricción formal para que T sea solo Double o Int . Por ejemplo, let event = Event(time: Date(), value: EventValue(value: "123abc")) también es posible. Si desea evitar estrictamente eso, la respuesta de Martin R da una solución ).
*Sin entrar en demasiados detalles, es más como una "cosa que crea un tipo" que un tipo en sí mismo.
Si la intención es tener un tipo de Event (único) con una propiedad EventValue que pueda contener un valor entero o doble, entonces una enum con valores asociados serviría para ese propósito:
enum EventValue { case ival(Int) case dval(Double) } struct Event { let time: Date let value: EventValue } let event1 = Event(time: Date(), value: .dval(40.3467)) let event2 = Event(time: Date(), value: .ival(1234))