Je migre un projet de Swift 2.2 vers Swift 3 , et j'essaie de me débarrasser des anciens types de données Cocoa lorsque cela est possible.
Mon problème est ici: migrer NSDecimalNumber
vers Decimal
.
J'avais l'habitude de relier NSDecimalNumber
à Double
dans les deux sens dans Swift 2.2 :
let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)
let doubleFromDecimal = decimalNumber.doubleValue
Maintenant, passez à Swift 3 :
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = ???
decimal.doubleValue
n'existe pas, ni Double(decimal)
, pas même decimal as Double
... Le seul piratage que je trouve est:
let doubleFromDecimal = (decimal as NSDecimalNumber).doubleValue
Mais ce serait complètement stupide d'essayer de se débarrasser de NSDecimalNumber
, et de devoir l'utiliser de temps en temps ...
Eh bien, soit j'ai raté quelque chose d'évident, et je vous demande pardon de perdre votre temps, ou bien il y a une lacune à résoudre, à mon avis ...
Merci d'avance pour votre aide.
Edit : Rien de plus sur le sujet sur Swift 4 .
Une autre solution qui fonctionne dans Swift 3 consiste à convertir la Decimal
en NSNumber
et à en créer la Double
.
let someDouble = Double(someDecimal as NSNumber)
NSDecimalNumber
et Decimal
sont pontés
La superposition rapide du framework Foundation fournit le nombre décimal structure, qui relie à la classe NSDecimalNumber. La décimale type de valeur offre les mêmes fonctionnalités que NSDecimalNumber type de référence, et les deux peuvent être utilisés indifféremment dans le code Swift qui interagit avec les API Objective-C. Ce comportement est similaire à comment Swift établit un pont entre les types standard string, numeric et collection et leur classes de fondation correspondantes. Apple Docs
mais comme avec d'autres types pontés, certains éléments manquent.
Pour retrouver la fonctionnalité, vous pouvez écrire une extension:
extension Decimal {
var doubleValue:Double {
return NSDecimalNumber(decimal:self).doubleValue
}
}
// implementation
let d = Decimal(floatLiteral: 10.65)
d.doubleValue
Decimal
dans Swift 3 n’est pas NSDecimalNumber
. C'est NSDecimal
, type complètement différent.
Vous devriez simplement continuer à utiliser NSDecimalNumber
comme vous le faisiez auparavant.
Solution efficace dans Swift 4
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = NSDecimalNumber(decimal: decimal).doubleValue
print(doubleFromDecimal)
Modifier: Sans NSDecimalNumber
/NSNumber
let double = 3.14
let decimal = Decimal(double)
if let doubleFromDecimal = Double(decimal.description){
print(doubleFromDecimal)
}
Vous êtes censé utiliser l'opérateur as
pour transtyper un type Swift en son type bridged sous-jacent Objective-C. Donc, utilisez simplement as
comme ceci.
let p = Decimal(1)
let q = (p as NSDecimalNumber).doubleValue
Dans Swift 4, Decimal
estNSDecimalNumber
. Voici la citation de la documentation officielle d'Apple dans Xcode 10.
Important
La superposition Swift au framework Foundation fournit la
Decimal
structure, qui relie à la classeNSDecimalNumber
. Pour plus Pour plus d'informations sur les types de valeur, voir Utilisation de frameworks Cocoa dans. Utilisation de Swift avec Cocoa et Objective-C (Swift 4.1).
Il n'y a plus de NSDecimal
. Il y avait un type NSDecimal
source de confusion dans Swift 3, mais cela semble être un bogue . Plus de confusion.
Je vois que l'OP n'est pas intéressé par Swift 4, mais j'ai ajouté cette réponse car le fait de ne parler que de (obsolète) Swift 3 m'a rendu confus.