W.r.t. funzioni built-in, penso che il più vicino si ottiene è il metodo di Foundation
copysign(_: Double, _: Double) -> Double
let foo = -15.2
let sign = copysign(1.0, foo) // -1.0 (Double)
Naturalmente necessitano di qualche tipo di conversione nel caso in cui non si sta operando su un numero di tipo Double
.
Tuttavia, non vedo alcun motivo per non creare la propria estensione adatta alle proprie esigenze, in particolare per una semplice funzione come sign
in quanto non è necessario gonfiarsi, ad es.
extension IntegerType {
func sign() -> Int {
return (self < 0 ? -1 : 1)
}
/* or, use signature: func sign() -> Self */
}
extension FloatingPointType {
func sign() -> Int {
return (self < Self(0) ? -1 : 1)
}
}
(qui cedendo 1
anche per 0
, come nell'esempio in questione).
(Edit per quanto riguarda il vostro commento qui sotto)
Una soluzione alternativa a quanto sopra potrebbe essere quella di definire il proprio protocollo con un'implementazione di default di sign()
, in modo che tutti i tipi conformi a questo protocollo avrebbe accesso a quel metodo sign()
.
protocol Signable {
init()
func <(lhs:Self, rhs:Self) -> Bool
}
extension Signable {
func sign() -> Int {
return (self < Self() ? -1 : 1)
}
}
/* extend signed integer types to Signable */
extension Int: Signable { } // already have < and init() functions, OK
extension Int8 : Signable { } // ...
extension Int16 : Signable { }
extension Int32 : Signable { }
extension Int64 : Signable { }
/* extend floating point types to Signable */
extension Double : Signable { }
extension Float : Signable { }
extension CGFloat : Signable { }
/* example usage */
let foo = -4.2
let bar = 42
foo.sign() // -1 (Int)
bar.sign() // 1 (Int)
Così che cosa è interessante è che io * non è stato * impazzire, non c'è davvero nulla * esattamente * come questo. Molto sorprendente. –