ios programmazione Converti rapidamente oggetto che è NSNumber in Double



swift syntax (1)

Aggiornare

Il comportamento di Swift qui è cambiato parecchio rispetto a 1.0. Non è stato così facile prima, ma Swift ha reso più difficile la conversione tra i tipi numerici perché vuole che tu sia esplicito su cosa fare con la perdita di precisione. Le tue nuove scelte ora assomigliano a questo:

var rating: NSNumber
var ratingDouble: Double

ratingDouble = rating as! Double // 1
ratingDouble = Double(exactly: rating)! // 2

ratingDouble = Double(truncating: rating) // 3
ratingDouble = rating.doubleValue // 4

if let x = rating as? Double { // 5
    ratingDouble = x
}

if let x = Double(exactly: rating) { // 6
    ratingDouble = x
}
  1. Ciò chiama Double._forceBridgeFromObjectiveC che chiama Double(exactly:) con Double , Int64 o UInt64 base al tipo memorizzato nella rating . Fallirà e causerà il crash dell'applicazione se il numero non è esattamente rappresentabile come Double . Ad esempio, UInt64.max ha più cifre di quelle che Double può memorizzare, quindi andrà in crash.

  2. Questo è esattamente lo stesso di 1 tranne che potrebbe anche bloccarsi su NaN poiché tale controllo non è incluso.

  3. Questa funzione restituisce sempre un Double ma perderà la precisione nei casi in cui 1 e 2 si arresterebbero. Questo letteralmente chiama doubleValue quando passa in un NSNumber .

  4. Come il 3.

  5. È come 1 tranne per il fatto che invece di bloccare l'app, restituirà nil e l'interno dell'istruzione non verrà valutato.

  6. Come 5, ma come 2 restituirà zero se il valore è NaN .

Se sai che la tua fonte di dati ha a che fare con il doppio, l'1-4 ti servirà quasi allo stesso modo. 3 e 4 sarebbero le mie prime scelte però.

Vecchia risposta per Swift 1 e 2

Ci sono molte cose che puoi fare:

var rating: NSNumber
var ratingDouble: Double

ratingDouble = rating as Double   // 1
ratingDouble = Double(rating)     // 2
ratingDouble = rating.doubleValue // 3
  1. Il primo elemento sfrutta il bridging Objective-C che consente di eseguire il cast di AnyObject e NSNumber come Double|Float|Int|UInt|Bool .
  2. Il secondo elemento presumibilmente attraversa un costruttore con la firma init(_ number: NSNumber) . Non sono riuscito a trovarlo nel modulo o nei documenti ma passare AnyObject generato un errore che non può essere implicitamente NSNumber a NSNumber quindi deve essere presente e non solo eseguire il bridging.
  3. Il terzo elemento non utilizza le funzionalità del linguaggio nello stesso modo. Si avvantaggia solo del fatto che doubleValue restituisce un Double .

Un vantaggio di 1 è che funziona anche con AnyObject quindi il tuo codice potrebbe essere:

let ratingDouble = self.prodResult!.prodsInfo.prodList[indexPath.row].avgRating! as Double

Si noti che ho rimosso il ? dalla tua funzione e spostato il ! in. Ogni volta che si usa! stai evitando la sicurezza di ? quindi non c'è motivo di fare entrambe le cose insieme.

Ho questo codice in Swift e funziona, ma penso che ci sia un modo migliore per ottenere il mio oggetto da NSNumber e convertirlo in Double:

var rating: NSNumber
var ratingDouble: Double

rating = self.prodResult?.prodsInfo.prodList[indexPath.row].avgRating as NSNumber!!

ratingDouble = Double(rating.doubleValue)




swift