Преобразование Int64
в Int
путем передачи значения Int64
инициализатору Int
всегда будет работать на 64-битной машине, а на 32-битной машине произойдет сбой, если целое число выходит за пределы диапазона Int32.min ... Int32.max
.
В целях безопасности используйте инициализатор init(truncatingIfNeeded:)
(ранее известный как init(truncatingBitPattern:)
в более ранних версиях Swift) для преобразования значения:
return Int(truncatingIfNeeded: rowid)
На 64-битной машине truncatingIfNeeded
ничего не сделает; вы просто получите 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(truncatingIfNeeded: i) // j = -539,222,987
let k = Int32(i) // crash!
Обновление для Swift 3/4
В дополнение к init(truncatingIfNeeded:)
, который все еще работает, 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
person
vacawama
schedule
26.09.2015