在 SQLite.swift 的过滤器中使用变量

Using variables in Filters in SQLite.swift

我在 XCode 6.3 测试版的应用程序中使用 SQLite.swift (Branch Swift-1-2)。 我能够创建 Database/Tables 并将条目插入表中。

到目前为止一切顺利。

现在当我有一个简单的场景如下:

class Foo {
   var id: Int?
   var name: String?
   /* constructor to create an instance ... */
}

// This is how the table column is defined
var id = Expression<Int64>("id")

// Function to update data in the table
func updateFoo(foo: Foo) -> Int? {
    // 'foos' is the table name
    let candidateFoo = foos.filter(super.id == foo.id!) //<----ERROR!!!
    let (rowsUpdated, statement) = candidateFoo.update(name <- foo.name!)

    if  let rowsUpdated = rowsUpdated {
        println("Succesfully updated \(rowsUpdated) row(s)")
        return rowsUpdated
    } else if statement.failed {
        println("Update failed. Reason: \(statement.reason)")
    }

    return nil
}

在注释行 \ <----ERROR!!! 上,我得到了编译时错误: 二元运算符“==”不能应用于 Expression 和 Int

类型的操作数

如果我直接在该行上使用 Int,则可以正常工作。例如

let candidateFoo = foos.filter(super.id == 3) // No Error!

但是,如果我只是这样做,它会再次失败并出现相同的错误:

var i = 3
let candidateFoo = foos.filter(super.id == i) // <----ERROR!!!

我明白错误是什么,但我无法解决它。我查看了 documentation 但我仍然卡住了。因此,我们将不胜感激。

更新:

将变量显式声明为 Int64 解决了问题:

var i:Int64 = 3
let candidateFoo = foos.filter(super.id == i) // No Error!

现在我想知道是否必须更改我的 class 定义,这将需要在代码中的多个位置进行更改。此外 official swift documentation 建议使用 Int 除非需要明确的大小。

You should use the word-sized Int type to store integer values, unless you require a type with a specific size or signedness.

此外,SQLite.swift 文档指出:

While Int64 is the basic, raw type (to preserve 64-bit integers on 32-bit platforms), Int and Bool work transparently.

那么我是否应该在我的 class 定义中明确使用 Int64,因为它映射到数据库?

您正在将 Foo 结构直接映射到 SQL 中的基础类型,因此您应该在两个地方使用相同的类型。如果在 32 位设备上需要 64 位精度(避免溢出等),应该使用 Int64。如果您不担心,请在两个地方使用 Int

var id = Expression<Int>("id")

If I use an Int directly on that line, then that works fine. Eg.

这是因为那实际上是一个 Int64,它符合 IntegerLiteralConvertible,因此可以推断文字的基础类型(您可以在此处阅读有关 Swift 的文字可转换的更多信息:http://nshipster.com/swift-literal-convertible/).

So should I be using the Int64 here explicitly in my class definition, since its mapped to a DB?

请记住,SQLite.swift 表达式层使您可以灵活地引用基础列类型,但是您想要(假设您 conform it to its Value protocol),所以再次强调:您可以使用 Int 如果这就是您在整个代码中处理值的方式,则可以自由使用。

除此之外,当您在 Swift 中使用不同的整数类型时,您可以内联转换它们。 例如,

let candidateFoo = foos.filter(super.id == Int64(foo.id!))