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 seNSDecimalNumbera 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