Могу ли я перенести Int64 прямо в Int?

В последнее время я использую SQLite.swift для создания базы данных приложений. И я определяю все мои столбцы INTEGER с помощью типа Int64 , как объясняет документация.

Но время от времени мне нужно, чтобы 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 } 

Будет ли это правильно?

Конечно, я протестировал его. И он работает, но я читал этот вопрос в Stackoverflow

И похоже, что у меня может быть проблема с 32-битными устройствами …

Если это неправильно, как я могу сделать Int64 в Int ?

Преобразование Int64 в Int путем передачи значения Int64 в инициализатор Int всегда будет работать на 64-битной машине, и он будет разбиваться на 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 в Playground – это 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 вводит отказоустойчивые инициализаторы для безопасного преобразования одного целочисленного типа в другой. С помощью init?(exactly:) вы можете передать один тип для инициализации другого, и он возвращает 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 

На самом деле я тоже работал с этой картой, и в основном я просто использовал противоположное решение. Всякий раз, когда вы видите, что типы не совпадают, просто выполните

 Int64(yourInt) 

(протестировано с Xcode 7, Swift 2.0)

  • Первые апрельские даты 80-х годов не удалось проанализировать в iOS 10.0
  • В Swift, как вы обнаруживаете, какие действия UIControlEvents инициировали действие?
  • Ошибка при установке coremltools
  • Учитывая CIImage, какой самый быстрый способ записать данные на диск?
  • Лучший способ определить переменные для размеров узлов на разных экранах в SpriteKit
  • Тип 'ViewController' не соответствует протоколу 'UITableViewDataSource'
  • Добавить подуровень CALayer с центром над UIImageView
  • Как узнать, когда в iOS выполняются параллельные HTTP-запросы?
  • Firebase запрашивает не вызывающий блок, когда нет результатов
  • FMDB не работает быстро?
  • Быстрая проблема с заголовком в Xcode 8 beta 6
  • Давайте будем гением компьютера.