我可以直接投Int64到Int?
我最近一直在使用SQLite.swift来构build我的应用程序数据库。 而且我正在用Int64
types定义所有的INTEGER
列,就像文档解释的那样。
但每隔一段时间我需要Int64
只是Int
。 所以我的问题是,如果我这样做:
//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 }
这是正确的吗?
当然,我testing了它。 它确实有效,但我正在阅读Stackoverflow中的这个问题
而且似乎我可能有32位设备的问题…
如果这是错误的,我怎样才能将Int64
投入Int
?
通过将Int64
值传递给Int
初始值设定项将Int64
转换为Int
将始终在64位计算机上工作,如果整数在Int32.min ... Int32.max
范围之外,将会在32位计算机上崩溃Int32.min ... Int32.max
为了安全起见,使用init(truncatingBitPattern)
初始值设定项来转换值:
return Int(truncatingBitPattern: rowid)
在64位机器上, truncatingBitPattern
什么也不做; 你只会得到一个Int
(它与Int64
大小一样)。
在32位的机器上,这会丢掉前32位,但它们都是零,那么你还没有丢失任何数据。 所以只要你的价值适合一个32位的Int
,你可以做到这一点,而不会丢失数据。 如果你的值超出了Int32.min ... Int32.max
的范围,这将会把Int64
的值改变成适合32位Int
,但是它不会崩溃。
你可以看到这是如何在一个游乐场的作品。 由于游戏中的Int
是64位的Int
,因此可以明确地使用Int32
来模拟32位系统的行为。
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!
Swift 3的更新
除了init(truncating:)
仍然有效,Swift 3引入了failable初始化器来安全地将一个整数types转换为另一个。 通过使用init?(exactly:)
你可以传递一个types来初始化另一个types,如果初始化失败,它将返回nil
。 返回的值是一个可选项,必须以通常的方式解包。
例如:
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") }
如果转换失败,这允许您应用nil合并运算符来提供默认值:
// return 0 if rowid is too big to fit into an Int on this device return Int(exactly: rowid) ?? 0
事实上,我也一直在使用这个框架,基本上我只是使用了相反的解决scheme。 每当你看到types不匹配只是做
Int64(yourInt)
(用Xcode 7,Swift 2.0testing)