Использование переменных в фильтрах в SQLite.swift

Я использую SQLite.swift (Branch Swift-1-2) в своем приложении в бета-версии XCode 6.3. Я могу создать базу данных/таблицы и вставить записи в таблицы.

Все идет нормально.

Теперь, когда у меня есть простой сценарий следующим образом:

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‹ Int64 > и Int

Если я использую Int непосредственно в этой строке, то это работает нормально. Например.

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

Но если я просто сделаю это, снова произойдет сбой с той же ошибкой:

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

Я понимаю, в чем ошибка, но не могу ее решить. Я просмотрел документацию но я все еще застрял. Поэтому любая помощь приветствуется.

Обновление:

Явное объявление переменной как Int64 решает проблему:

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

Теперь мне интересно, нужно ли мне изменить определение класса, что потребует изменений в нескольких местах кода. Также официальная документация по Swift рекомендует использовать Int, если только требуется явный размер.

Вы должны использовать тип Int размером с слово для хранения целочисленных значений, если только вам не требуется тип с определенным размером или знаком.

Кроме того, в документации SQLite.swift указано, что:

В то время как Int64 является базовым необработанным типом (для сохранения 64-битных целых чисел на 32-битных платформах), Int и Bool работают прозрачно.

Так должен ли я явно использовать Int64 здесь в определении моего класса, поскольку он сопоставлен с БД?


person rgamber    schedule 15.03.2015    source источник
comment
Я думал, что этот ответ может помочь вам stackoverflow.com/questions/29054958/   -  person Victor Sigler    schedule 15.03.2015
comment
Я не верю, что это проблема. Я понимаю (думаю!) разницу между id?, id! и id = 3. Смотрите мое обновление выше. Даже если я объявляю локальный var i = 3 и использую его в filter(), я все равно получаю ту же самую ошибку.   -  person rgamber    schedule 15.03.2015


Ответы (1)


Вы сопоставляете свою структуру Foo непосредственно с базовыми типами в SQL, поэтому вы должны использовать один и тот же тип в обоих местах. Если вам нужна 64-битная точность на 32-битных устройствах (во избежание переполнения и т. д.), вы должны использовать Int64. Если вас это не беспокоит, используйте Int в обоих местах:

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

Если я использую Int непосредственно в этой строке, то это работает нормально. Например.

Это потому, что на самом деле это Int64, который соответствует IntegerLiteralConvertible, поэтому выводится базовый тип литерала (вы можете прочитать больше о конвертируемых литералах Swift здесь: http://nshipster.com/swift-literal-convertible/).

Так должен ли я явно использовать Int64 здесь в определении моего класса, поскольку он сопоставлен с БД?

Имейте в виду, что уровень выражений SQLite.swift дает вам возможность обращаться к базовым типам столбцов любым удобным для вас способом (при условии, что вы соответствуйте его протоколу Value), так что еще раз: вы можете свободно использовать Int, если именно так вы обрабатываете значение в своем коде.

Помимо всего этого, когда вы работаете с различными целочисленными типами в Swift, вы можете преобразовать их в строку. Например,

let candidateFoo = foos.filter(super.id == Int64(foo.id!))
person stephencelis    schedule 15.03.2015
comment
Это проясняет мою точную точку путаницы! Спасибо за ответ! - person rgamber; 15.03.2015