2015-09-26 10 views
15

Ich habe in letzter Zeit SQLite.swift verwendet, um meine App-Datenbank zu erstellen. Und ich definiere alle meine INTEGER Spalten mit einem Int64 Typ, wie die Dokumentation erklärt.Kann ich Int64 direkt in Int?

Aber hin und wieder brauche ich das Int64 um nur Int zu sein. Also meine Frage ist, wenn ich dies tun:

//Create a table with Int instead of Int64 
let test_id = Expression<Int>("test_id") 
let tests = db["tests"] 

db.create(table: tests, ifNotExists: true){ t in 
    t.column(test_id) 
} 


class func insertTest(t: Int) -> Int{ 
    //insert.rowid returns an Int64 type 
    let insert = tests.insert(test_id <- t) 
    if let rowid = insert.rowid{ 
     //directly cast Int64 into Int 
     return Int(rowid) 
    } 
    return 0 
} 

Wird es richtig sein?

Natürlich habe ich es getestet. Und das tut sie funktioniert, aber ich lese this question in Stackoverflow

Und es scheint, dass ich ein Problem mit 32-Bit-Geräten haben könnte ...

Wenn dies falsch ist, wie ich Int64 in Int werfen kann?

+0

Wenn der Wert des Int64 größer als 2^31 und Int 32 Bits tun übereinstimmen, was zu tun denkst du würde passieren? – zaph

+0

@zaph Überlauf? Ich weiß nicht ... –

+0

@zaph können Sie mir erklären? –

Antwort

22

eine Int64 zu Int durch Hindurchleiten des Int64 Wert dem Int Initialisierer Converting wird auf einer 64-Bit-Maschine immer funktionieren, und es wird auf einer 32-Bit-Maschine abstürzen, wenn die ganze Zahl außerhalb des Bereichs Int32.min ... Int32.max ist.

Zur Sicherheit verwenden, um die init(truncatingBitPattern) initializer den Wert zu konvertieren:

return Int(truncatingBitPattern: rowid) 

Auf einer 64-Bit-Maschine, wird die truncatingBitPattern nichts tun; Sie erhalten nur eine Int (die die gleiche Größe wie eine Int64 ist sowieso).

Auf einer 32-Bit-Maschine werden die obersten 32 Bits verworfen, aber es sind nur Nullen, dann haben Sie keine Daten verloren. Solange Ihr Wert in ein 32-Bit Int passt, können Sie dies tun, ohne Daten zu verlieren. Wenn Ihr Wert außerhalb des Bereichs Int32.min ... Int32.max liegt, ändert sich der Wert des Int64 in etwas, das in ein 32-Bit Int passt, aber es wird nicht abstürzen.


Sie können sehen, wie dies in einem Spielplatz funktioniert. Da Int in einem Playground ein 64-Bit Int ist, können Sie explizit ein Int32 verwenden, um das Verhalten eines 32-Bit-Systems zu simulieren.

let i: Int64 = 12345678901 // value bigger than maximum 32-bit Int 

let j = Int32(truncatingBitPattern: i) // j = -539,222,987 
let k = Int32(i)      // crash! 

Update für Swift 3

Neben init(truncating:), die noch funktioniert, Swift 3 führt failable initializers sicher zum anderen ein Integer-Typ zu konvertieren. Wenn Sie init?(exactly:) verwenden, können Sie einen Typ übergeben, um einen anderen zu initialisieren. Wenn die Initialisierung fehlschlägt, wird nil zurückgegeben. Der zurückgegebene Wert ist ein optionaler Wert, der auf die übliche Weise ausgepackt werden muss.

Zum Beispiel:

let i: Int64 = 12345678901 

if let j = Int32(exactly: i) { 
    print("\(j) fits into an Int32") 
} else { 
    // the initialization returned nil 
    print("\(i) is too large for Int32") 
} 

Auf diese Weise können Sie die nil koaleszierende Operator anzuwenden einen Standardwert zu liefern, wenn die Konvertierung fehlschlägt:

// return 0 if rowid is too big to fit into an Int on this device 
return Int(exactly: rowid) ?? 0 
1

als eine Angelegenheit der Tatsache, ich habe Ich habe auch mit diesem Framework gearbeitet, und im Grunde habe ich einfach die gegenteilige Lösung benutzt. Jedes Mal, wenn Sie sehen, dass Arten nicht nur

Int64(yourInt) 

(getestet mit Xcode 7, Swift 2.0)

Verwandte Themen