你真的知道%格式化字符串嗎汁讼?

我們從C語言開始就學(xué)會了用 % 來格式化輸出字符串淆攻,這看起來非常簡單自然。

在iOS開發(fā)時(shí)我們依然會用到它嘿架。但是我敢肯定很多人其實(shí)并不知道format到底是按照什么邏輯來識別參數(shù)并正確輸出的瓶珊。

下面我姑且使用Swift來做例子說明。

眾所周知耸彪,在 Swift 里伞芹,我們使用 print 是支持字符串插值的,這樣,我們就可以不借助于占位符唱较,也不用再去記憶類型所對應(yīng)的字符表示扎唾,就能很簡單地輸出各種類型的字符串描述了。

let a:Int = 1
let b:Float = 2.22
let c:String = "hello"
print("\(a)  \(b)  \(c)") // 不需要 %d %f %s 這樣的格式化

但是有些場景還是需要%格式化的南缓,比如我們需要得到一個這樣的時(shí)間間隔字符串:

08:30 - 11:40 //時(shí)間間隔

這個時(shí)候直接使用字符串插值 的方式就比較麻煩了胸遇,此時(shí)還是要借助%來格式化,于是我們這樣測試:

//iphon6 測試
let h1: Int = 8
let m1: Int = 30
let h2: Int = 11
let m2: Int = 40
let str = String(format: "%02d:%02d - %02d:%02d", h1, m1, h2, m2)
print(str)  //輸出08:30 - 11:40

沒毛病西乖,接下來我們故意把上面的Int改成Int64試試

//iphon6 測試
let h1: Int64 = 8
let m1: Int64 = 30
let h2: Int64 = 11
let m2: Int64 = 40
let str = String(format: "%02d:%02d - %02d:%02d", h1, m1, h2, m2)
print(str)  //輸出08:30 - 11:40

也沒毛病狐榔,別急,我們把這代碼運(yùn)行到 iphone5上試試获雕,你們猜結(jié)果是啥薄腻?想10秒鐘
0
1
2
3
4
5
6
7
8
9
OK, 公布答案:

輸出的是:

08:00 - 30:00

猜對了嗎届案?

看到這樣的結(jié)果估計(jì)大家都能看出端倪了吧庵楷,這30明顯是m1的值,卻出現(xiàn)在h2的位置楣颠。
那么為啥在iphon6尽纽、iphoneX,甚至iphone5s上都沒問題呢童漩?

原來蘋果從iphone5s之后開始全線升級為64位系統(tǒng)了弄贿,所以問題就出現(xiàn)在32位系統(tǒng)與64位系統(tǒng)的區(qū)別。

于是矫膨,我大膽猜測:

%格式化 其實(shí)并不是跟后面的參數(shù)一一對應(yīng)的差凹,而是將后面參數(shù)按字節(jié)排起來,然后按照%后面的格式所需的字節(jié)數(shù)依次取的

帶著這種猜測我們繼續(xù)實(shí)驗(yàn)侧馅, 還在iphone5上測試危尿,我們把%d 改成%lld:

let str = String(format: "%02lld:%02lld - %02lld:%02lld", h1, m1, h2, m2)
print(str)  //輸出08:30 - 11:40

果然對了,因?yàn)?lld是取long long類型的馁痴,在32位上long long是8字節(jié)的谊娇,剛好對應(yīng)Int64的64位。

為了進(jìn)一步驗(yàn)證我的猜想罗晕,我們換一個測試:

//iphone5 測試
let h1: Int64 = 8
let m1: Int64 = 30
let h2: Int64 = 11
let m2: Int64 = 40
let str = String(format: "%02d:%02d - %02d:%02d", h1, m1 )//注意這里只有兩個參數(shù)
print(str)  //輸出08:00 - 30:00

看到?jīng)]济欢,我們有4個 %,但只有2個參數(shù)居然沒有報(bào)錯小渊,這印證了我的猜想船逮。

其實(shí),上面這種格式化類型和實(shí)際類型不匹配以及參數(shù)個數(shù)不夠的情況應(yīng)該有warnning 或者error提示的粤铭,然而Swift都沒有挖胃,OC會有warnning提示,同理,C語言也會有Warnning酱鸭, 從這一點(diǎn)看吗垮,Swift的語法檢查不如OC的嚴(yán)格。

image.png

好了凹髓,看到這里你應(yīng)該明白了吧烁登!

Really?

再回頭看看開始的那個例子:

//iphon6 測試
let h1: Int64 = 8
let m1: Int64 = 30
let h2: Int64 = 11
let m2: Int64 = 40
let str = String(format: "%02d:%02d - %02d:%02d", h1, m1, h2, m2)
print(str)  //輸出08:30 - 11:40

有沒有疑問呢蔚舀?

我當(dāng)時(shí)是有疑問的饵沧,按說%d應(yīng)該是想格式化Int類型的,那為什么在64位的iphone6上 可以正確地輸出Int64的值呢赌躺?難道在64位的iOS系統(tǒng)中Int是64位的狼牺?
按照以前的Linux系統(tǒng)的經(jīng)驗(yàn),64位系統(tǒng)應(yīng)該只是說指針是64位(8字節(jié))的礼患,Int還是32位的啊是钥。于是我查找了Swift中Int的定義:

image.png

原來如此,iOS的64位系統(tǒng)中Int是64位的缅叠,所以上面%d取的也是64位的悄泥,也就沒問題了。

這個跟一般的類Unix系統(tǒng)是不一樣的肤粱,我們看下面這張圖:

image.png

其中弹囚,
I表示:int類型
L表示:long類型
P表示:pointer指針類型
32表示:32位系統(tǒng)
64表示64位系統(tǒng)

如:LP64表示,在64位系統(tǒng)下的long類型和pointer類型長度為64位领曼。
64位Linux 使用了 LP64 標(biāo)準(zhǔn)余寥,即:long類型和pointer類型長度為64位,int還是32位的悯森。

由上可知iOS系統(tǒng)( Darwin Mach 內(nèi)核)是使用了ILP64標(biāo)準(zhǔn)。

這次真的明白了吧绪撵!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瓢姻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子音诈,更是在濱河造成了極大的恐慌幻碱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件细溅,死亡現(xiàn)場離奇詭異褥傍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)喇聊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門恍风,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事朋贬】ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵锦募,是天一觀的道長摆屯。 經(jīng)常有香客問我,道長糠亩,這世上最難降的妖魔是什么虐骑? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮赎线,結(jié)果婚禮上廷没,老公的妹妹穿的比我還像新娘。我一直安慰自己氛驮,他們只是感情好腕柜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著矫废,像睡著了一般盏缤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蓖扑,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天唉铜,我揣著相機(jī)與錄音罚屋,去河邊找鬼浙巫。 笑死,一個胖子當(dāng)著我的面吹牛试溯,可吹牛的內(nèi)容都是我干的柜去。 我是一名探鬼主播灰嫉,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嗓奢!你這毒婦竟也來了讼撒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤股耽,失蹤者是張志新(化名)和其女友劉穎根盒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體物蝙,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炎滞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诬乞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片册赛。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡钠导,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出击奶,到底是詐尸還是另有隱情辈双,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布柜砾,位于F島的核電站湃望,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痰驱。R本人自食惡果不足惜证芭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望担映。 院中可真熱鬧废士,春花似錦、人聲如沸蝇完。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽短蜕。三九已至氢架,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間朋魔,已是汗流浹背岖研。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留警检,地道東北人孙援。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像扇雕,于是被迫代替她去往敵國和親拓售。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,814評論 1 10
  • 1镶奉、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,982評論 3 119
  • 慧骃的語言中础淤,絲毫沒有那些關(guān)于丑惡的詞匯。它們的詞匯不夠豐富腮鞍,因?yàn)樗鼈兊男枰约扒橛任覀兩伲欢鴮?shí)際上莹菱,有關(guān)丑惡...
    顧曉雨媽媽閱讀 2,048評論 0 0
  • 我一般不追捧暢銷書移国,但我卻用最快的時(shí)間讀完了這本《島上書店》。 隨著閱讀的繼續(xù)道伟,書中人物漸漸揭開面紗迹缀。31歲單身未...
    曲水憑欄閱讀 491評論 0 4
  • 唯有星空浩瀚的夜晚 最適合靜靜的思念 那種淡淡的感覺 就著茶杯里散發(fā)出來的香氣 吸入了藏污納垢的肺里 夜晚沒有露珠...
    年輪止閱讀 309評論 2 5