我可以直接将Int64转换为Int吗?
我最近一直在使用SQLite.swift来构建我的app数据库。
我正在使用 Int64
类型定义所有 INTEGER
列,如文档所述。
I've been using SQLite.swift lately to build my app database.
And I'm defining all my INTEGER
columns with a Int64
type, like the documentation explains.
但每隔一段时间我就需要 Int64
只需 Int
。
所以我的问题是,如果我这样做:
But every once in a while I need that Int64
to be just Int
.
So my question is, if I do this:
//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
}
这是正确的吗?
当然我测试了它。它确实有效,但我正在阅读在Stackoverflow中这个问题/ a>
Of course I tested it. And it does works, but I was reading this question in Stackoverflow
似乎我可能遇到32位设备的问题......
And it seems that I could have a problem with 32 bits devices...
如果这是错误的,如何将 Int64
转换为 Int
?
If this is wrong, how can I cast Int64
into Int
?
通过传递 Int64 转换为 Int
$ c> Int64 Int
初始化程序的值将始终在64位计算机上运行,如果在32位计算机上运行,它将崩溃整数超出范围 Int32.min ... Int32.max
。
Converting an Int64
to Int
by passing the Int64
value to the Int
initializer will always work on a 64-bit machine, and it will crash on a 32-bit machine if the integer is outside of the range Int32.min ... Int32.max
.
为安全起见, init(truncatingIfNeeded :)
初始化程序(以前在早期的Swift版本中称为 init(truncatingBitPattern:)
)转换值:
For safety use the init(truncatingIfNeeded:)
initializer (formerly known as init(truncatingBitPattern:)
in earlier Swift versions) to convert the value:
return Int(truncatingIfNeeded: rowid)
在a 64位机器, truncatingIfNeeded
什么都不做;你只需得到 Int
(无论如何都与 Int64
相同)。
On a 64-bit machine, the truncatingIfNeeded
will do nothing; you will just get an Int
(which is the same size as an Int64
anyway).
在32位机器上,这将丢弃前32位,但它们都是零,那么你没有丢失任何数据。因此,只要您的值适合32位 Int
,就可以在不丢失数据的情况下执行此操作。如果您的值超出范围 Int32.min ... Int32.max
,这将更改 Int64 $ c $的值c>进入适合32位
Int
的东西,但它不会崩溃。
On a 32-bit machine, this will throw away the top 32 bits, but it they are all zeroes, then you haven't lost any data. So as long as your value will fit into a 32-bit Int
, you can do this without losing data. If your value is outside of the range Int32.min ... Int32.max
, this will change the value of the Int64
into something that fits in a 32-bit Int
, but it will not crash.
您可以在Playground中看到它的工作原理。由于Playground中的 Int
是64位 Int
,因此您可以显式使用 Int32
模拟32位系统的行为。
You can see how this works in a Playground. Since Int
in a Playground is a 64-bit Int
, you can explicitly use an Int32
to simulate the behavior of a 32-bit system.
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!
Swift 3/4更新
除了 init(truncatingIfNeeded :)
之外,Swift 3还可以安全地引入可用的初始值设定项将一个整数类型转换为另一个。通过使用 init?(确切地说:)
,您可以传递一种类型来初始化另一种类型,如果初始化,它将返回 nil
失败。返回的值是可选的,必须以通常的方式解包。
In addition to init(truncatingIfNeeded:)
which still works, Swift 3 introduces failable initializers to safely convert one integer type to another. By using init?(exactly:)
you can pass one type to initialize another, and it returns nil
if the initialization fails. The value returned is an optional which must be unwrapped in the usual ways.
例如:
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 coalescing operator 来提供默认值:
This allows you to apply the nil coalescing operator to supply a default value if the conversion fails:
// return 0 if rowid is too big to fit into an Int on this device
return Int(exactly: rowid) ?? 0