2015-09-26 46 views
15

我最近一直在使用SQLite.swift來構建我的應用程序數據庫。 而且我正在定義所有INTEGER列,其中包含Int64類型,如文檔解釋。我可以直接將Int64投入Int嗎?

但每隔一段時間我需要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 
} 

會不會是正確的嗎?

當然,我測試了它。而它的作品,但我讀this question in Stackoverflow

它似乎我能與32位設備的一個問題...

如果這是錯誤的,我怎麼能投Int64Int

+0

(在Xcode 7,雨燕2.0測試)如果Int64類型的值大於2^31和int是32位做什麼你認爲會發生? – zaph

+0

@zaph溢出?我不知道... –

+0

@ zaph你能解釋一下嗎? –

回答

22

Int64值傳遞給Int初始化將始終在64位機器上工作的轉換到Int64Int,它會在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的值,但不會崩潰。


你可以看到這是如何工作的一個遊樂場。由於Playground中的Int是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! 

更新斯威夫特3

除了init(truncating:)仍然有效,斯威夫特3引入failable初始化到一個整數類型安全地轉換爲另一種。通過使用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") 
} 

這使您可以應用零合併運算如果轉換失敗,以提供一個默認值:

// return 0 if rowid is too big to fit into an Int on this device 
return Int(exactly: rowid) ?? 0 
1

事實上我已經事項我也一直在使用這個框架,基本上我只是使用了相反的解決方案。每當你看到一個類型不匹配,只是做

Int64(yourInt) 

相關問題