generic functions basics ios generics swift

ios - functions - Restricción de tipo genérico para tipo numérico solamente



swift generics (4)

Estoy tratando de averiguar cómo implementar una restricción de tipo para una clase genérica (en Swift) que limitará los tipos genéricos solo a tipos numéricos. Por ejemplo Double, Int, etc., pero no string. Gracias por cualquier ayuda.


Como se mencionó here y here , el protocolo Numeric ahora es parte de Swift 4, así que, por ejemplo, puede sobrecargar + para tuplas numéricas de la siguiente manera:

func +<T : Numeric> (x: (T, T), y: (T, T)) -> (T, T) { return (x.0 + y.0, x.1 + y.1) } (1,1) + (2,3) // (3, 4) : (Int, Int) (1.25, 1.5) + (2.5, 2.25) // (3.75, 3.75) : (Double, Double)


Puede enrollar el suyo con una enumeración:

enum Numeric { case NInt(Int) case NUInt(UInt) case NFloat(Float) case NDouble(Double) }

Luego úsalo en tu código:

func myFunc(x: Numeric) -> Numeric { switch x { case let NInt(i): return i + 1 case let NUInt(u): return u + 1 case let NFloat(f): return f + 1 case let NDouble(d): return d + 1 } }

O simplemente puede usar NSNumber, que enrolla varios tipos numéricos en un tipo de manta.


Puede especificar restricciones de tipo (usando ambas clases y protocolos) para una clase genérica (la misma sintaxis se aplica a las funciones) usando corchetes angulares:

class Foo<T: Equatable, U: Comparable> { }

Para especificar más de un requisito en un solo tipo, use una cláusula where :

class Foo<T: UIViewController where T: UITableViewDataSource, T: UITextFieldDelegate> { }

Sin embargo, no parece que pueda especificar requisitos opcionales en una cláusula de parámetro genérico, por lo que una posible solución es crear un protocolo que todos los tipos numéricos implementen a través de extensiones y luego restringir su clase a ese requisito:

protocol Numeric { } extension Float: Numeric {} extension Double: Numeric {} extension Int: Numeric {} class NumberCruncher<C1: Numeric> { func echo(num: C1)-> C1 { return num } } NumberCruncher<Int>().echo(42) NumberCruncher<Float>().echo(3.14)


Strideable es el protocolo estándar más pequeño que cumple cada tipo de número estándar, pero también tiene algunos tipos más que lo conforman. http://swiftdoc.org/protocol/Strideable/hierarchy/

O puede usar IntegerType y FloatingPointType .