中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Swift中一個字符引發的Crash實例分析

發布時間:2022-02-22 13:39:06 來源:億速云 閱讀:147 作者:iii 欄目:開發技術

這篇文章主要介紹“Swift中一個字符引發的Crash實例分析”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Swift中一個字符引發的Crash實例分析”文章能幫助大家解決問題。

最近因為一個字符引發了 Crash,因為實際的業務場景不便描述,這里便用一段測試代碼作說明。

話不多說,直接上代碼:

let testCharacters: Set<Character> = ["!", "\"", "$", "%", "&", "'", "+", ",", "<", "=", ">", "@", "[", "]", "`", "{", "}"]
let testString = "@`Hello World?!"
var result: UInt8 = 0
for character in testString {
    if testCharacters.contains(character) {
	result += character.asciiValue!
    }
}

上面的代碼做的事情是:取出 testString 里特定字符的 ASCII 碼,然后相加。

我們來 Review 下這段代碼,有經驗的同學應該立馬嗅到了代碼里的壞味道:character.asciiValue! 這里用了強解。

那這里的強解用得合理嗎?因為定義在 testCharacters 里的字符肯定都有對應的 ASCII 碼,咋一看這里用強解也沒關系。

但是,如果我們實際跑一下,就會出現因為 asciiValue 為 nil 的強解 Crash 了。這是為什么呢?

關鍵在于 testString 里面包含了 全角字符。testString 里的后一個 ? 是一個全角字符,它是沒有 asciiValue 的。

我們可以在 Swift Playgrounds 里執行下面的代碼得到答案:

let halfWidth = "`"
halfWidth.lengthOfBytes(using: .utf8) // 1
halfWidth.first!.isASCII // true
halfWidth.first!.asciiValue // 96

let fullWidth = "?"
fullWidth.lengthOfBytes(using: .utf8) // 3
fullWidth.first!.isASCII // false
fullWidth.first!.asciiValue // nil
// Character 實現 Equatable 協議,判斷出兩個值是相等的。
halfWidth == fullWidth // true

從上面代碼執行結果可以看到,halfWidth 這個半角字符占一個字節長度,對應的 ASCII 碼為 96 而全角字符 fullWidth 占三個字節長度,其 asciiValue 為空的。

Swift 數組的 contains 方法利用的是 Equatable 協議 , 從上面代碼里 halfWidth == fullWidth 的結果為 true 來看,Character 實現的 Equatable 協議并沒有考慮字符全角/半角的情況。

用肉眼看,完全看不出字符有何不同,而 contains 方法結果為 true 也影響了我們的判斷,以為這個強解是 OK 的,稍不注意就導致了 Crash。

最后,從維基百科上整理了關于全角/半角的歷史知識:

在早期的計算機中,英語或拉丁字母語言使用的系統,每一個字母或符號,都是使用一字節的空間(一字節由 8 比特組成,共256個編碼空間)來儲存;而漢語、日語及韓語文字,由于數量大大超過256個,故慣常使用兩字節來儲存一個字符。所以這原本是編碼層面的“單字節”“雙字節”的問題。

當時的電腦使用等寬字體(如DOS、部分文字編輯器等)時,字體也就順應這種編碼形式,將中日韓文字的寬度繪制成拉丁字母和數字的兩倍,這樣字符的編碼存儲和顯示寬度可以一一對應起來:

  • 單字節文字 顯示成 半寬,

  • 雙字節文字 顯示成 全寬。

因此當時的用戶就開始習慣稱中、日、韓等文字為 全角字符,而稱拉丁字母或數字為 半角字符。

但是,后來計算機的文字編碼技術已經發生很大變化,存儲一個字符可能用一個、兩個、四個或者更多的字節。一個英文字符即使顯示為半寬,依照不同的編碼方式,并不一定是用一個字節存儲。

因此,現在字符編碼存儲和字符顯示寬度的已經沒有一一對應關系。

但是由于字符編碼和字形寬度曾經的對應關系,很多用戶一直習慣性地使用"全角/半角"詞匯。

因此現在的 全角字 可能是指:

  • 用兩個字節存儲的字符

  • ASCII(所謂半角英文和數字)以外所有的字符

  • 顯示上字身寬度為一比一正方形的字形。

關于“Swift中一個字符引發的Crash實例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新竹市| 东乡县| 秦安县| 鸡泽县| 北碚区| 龙胜| 砀山县| 华宁县| 松阳县| 甘谷县| 明星| 盱眙县| 新竹市| 乳源| 银川市| 界首市| 沙洋县| 海南省| 巴马| 临沧市| 会同县| 六枝特区| 乃东县| 高清| 福贡县| 阳山县| 榆中县| 汉源县| 海安县| 科技| 垫江县| 确山县| 宁海县| 夏河县| 宁乡县| 鲁山县| 元氏县| 全椒县| 泾川县| 扶余县| 高台县|