ios swift sqlite.swift

ios - ¿Puedo lanzar Int64 directamente en Int?



swift sqlite.swift (3)

He estado usando SQLite.swift últimamente para construir mi base de datos de aplicaciones. Y estoy definiendo todas mis columnas INTEGER con un tipo Int64 , como explica la documentación.

Pero de vez en cuando necesito que Int64 sea ​​solo Int . Así que mi pregunta es, si hago esto:

//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 }

¿Será correcto?

Por supuesto que lo probé. Y funciona, pero estaba leyendo esta pregunta en Stackoverflow

Y parece que podría tener un problema con dispositivos de 32 bits ...

Si esto está mal, ¿cómo puedo lanzar Int64 en Int ?


Convertir un Int64 a Int al pasar el valor de Int64 al inicializador Int siempre funcionará en una máquina de 64 bits y se bloqueará en una máquina de 32 bits si el número entero está fuera del rango Int32.min ... Int32.max .

Por seguridad, use el init(truncatingIfNeeded:) (anteriormente conocido como init(truncatingBitPattern:) en versiones anteriores de Swift) para convertir el valor:

return Int(truncatingIfNeeded: rowid)

En una máquina de 64 bits, truncatingIfNeeded no hará nada; solo obtendrás un Int (que es el mismo tamaño que un Int64 todos modos).

En una máquina de 32 bits, esto eliminará los 32 bits superiores, pero si todos son ceros, no habrá perdido ningún dato. Entonces, siempre que su valor se ajuste a un Int 32 bits, puede hacerlo sin perder datos. Si su valor está fuera del rango Int32.min ... Int32.max , esto cambiará el valor del Int64 en algo que se ajuste a un Int 32 bits, pero no se bloqueará.

Puedes ver cómo funciona esto en un parque infantil. Dado que Int en un área de juegos es un Int 64 bits, puede usar explícitamente un Int32 para simular el comportamiento de un sistema de 32 bits.

let i: Int64 = 12345678901 // value bigger than maximum 32-bit Int let j = Int32(truncatingIfNeeded: i) // j = -539,222,987 let k = Int32(i) // crash!

Actualización para Swift 3/4

Además de init(truncatingIfNeeded:) que todavía funciona, Swift 3 introduce inicializadores failable para convertir de forma segura un tipo entero a otro. Al usar init?(exactly:) puede pasar un tipo para inicializar otro, y devuelve nil si la inicialización falla. El valor devuelto es un opcional que se debe desempaquetar de la forma habitual.

Por ejemplo:

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") }

Esto le permite aplicar el operador de unión nula para proporcionar un valor predeterminado si la conversión falla:

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


De hecho, también he estado trabajando con este marco, y básicamente he usado la solución opuesta. Cada vez que veas que los tipos no coinciden solo hazlo

Int64(yourInt)

(probado con Xcode 7, Swift 2.0)


Si está seguro de que el valor de Int64 se puede representar exactamente como un Int , use Int(truncatingIfNeeded:) , por ejemplo:

let salary: Int64 = 100000 let converted = Int(truncatingIfNeeded: salary)

Para compatibilidad con dispositivos de 32 bits, el rango para Int es de -2147483648 a 2147483647, igual que Int32 . Los valores fuera de ese rango se descartarán silenciosamente sus bits de orden superior. Esto se traduce en basura, a menudo del signo opuesto.

Si el valor puede estar fuera del rango y desea controlar esa condición, use Int(exactly:) , por ejemplo:

if let converted = Int(exactly: salary) { // in range ... converted ... } else { // out-of-range ... }

En el caso específico de los rowids, el uso de Int64 lugar de Int fue una elección deliberada de diseño de API, y el truncado a Int podría ser un error.