ios - whatwg - Conversión de decimal a doble en Swift 3
whatwg español (5)
Estoy migrando un proyecto de Swift 2.2 a Swift 3 , y trato de deshacerme de los viejos tipos de datos de Cocoa cuando sea posible.
Mi problema está aquí: migrar NSDecimalNumber
a Decimal
.
Solía unir NSDecimalNumber
para Double
ambas formas en Swift 2.2 :
let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)
let doubleFromDecimal = decimalNumber.doubleValue
Ahora, cambiando a Swift 3 :
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = ???
decimal.doubleValue
no existe, ni Double(decimal)
, ni siquiera decimal as Double
... El único hack que se me ocurre es:
let doubleFromDecimal = (decimal as NSDecimalNumber).doubleValue
Pero eso sería completamente estúpido tratar de deshacerse de NSDecimalNumber
, y tener que usarlo de vez en cuando ...
Bueno, o me he perdido algo obvio, y le pido perdón por perder el tiempo, o hay una laguna que debe abordarse, en mi opinión ...
Gracias de antemano por tu ayuda.
Edición : Nada más sobre el tema en Swift 4 .
Otra solución que funciona en Swift 3 es convertir el Decimal
en NSNumber
y crear el Double
partir de eso.
let someDouble = Double(someDecimal as NSNumber)
Se supone que debe utilizar as
operador para convertir un tipo Swift a su tipo subyacente de Objective-C. Así que solo úsalo as
este.
let p = Decimal(1)
let q = (p as NSDecimalNumber).doubleValue
En Swift 4, Decimal
es NSDecimalNumber
. Aquí hay una cita de la documentación oficial de Apple en Xcode 10.
Importante
La superposición Swift al marco de Foundation proporciona la estructura
Decimal
, que seNSDecimalNumber
a la claseNSDecimalNumber
. Para obtener más información sobre los tipos de valor, consulte Trabajar con Cocoa Frameworks en el uso de Swift con Cocoa y Objective-C (Swift 4.1).
NSDecimal
no hay NSDecimal
. Hubo NSDecimal
tipo NSDecimal
confuso en Swift 3, pero parece ser un error. No más confusión.
Nota
Veo que el OP no está interesado en Swift 4, pero agregué esta respuesta porque mencionar solo sobre Swift 3 (desactualizado) me confundió.
Solución que funciona en Swift 4.
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = NSDecimalNumber(decimal: decimal).doubleValue
print(doubleFromDecimal)
Edición: Sin NSDecimalNumber
/ NSNumber
let double = 3.14
let decimal = Decimal(double)
if let doubleFromDecimal = Double(decimal.description){
print(doubleFromDecimal)
}
Decimal
en Swift 3 no es NSDecimalNumber
. Es tipo NSDecimal
, completamente diferente.
Solo debes seguir usando NSDecimalNumber
como lo hiciste antes.
NSDecimalNumber
y Decimal
están puenteados
La superposición Swift al marco de Foundation proporciona la estructura decimal, que se une a la clase NSDecimalNumber. El tipo de valor decimal ofrece la misma funcionalidad que el tipo de referencia NSDecimalNumber, y los dos se pueden usar indistintamente en el código Swift que interactúa con las API de Objective-C. Este comportamiento es similar a cómo Swift vincula los tipos de serie, numéricos y colección estándar a sus clases de Foundation correspondientes. Apple Docs
pero como con algunos otros tipos de puentes, faltan ciertos elementos.
Para recuperar la funcionalidad puedes escribir una extensión:
extension Decimal {
var doubleValue:Double {
return NSDecimalNumber(decimal:self).doubleValue
}
}
// implementation
let d = Decimal(floatLiteral: 10.65)
d.doubleValue