91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

深入理解Swift中的Substring和String

發布時間:2020-09-17 09:05:41 來源:腳本之家 閱讀:1165 作者:Greg Heo (@gregheo) 欄目:編程語言

前言

為文本字符串添加特性或者語法糖在各種編程語言中都很普遍。就拿大家都很熟悉的 C 語言舉例,C 字符串本質是一個字符數組(characters array),但是每次輸入字符串的時候不用輸入 ['h','e','l','l','o'] ,直接打 hello 就可以了,因為這個操作編譯器幫你做了。

更高級的語言比如 Swift 處理字符串就不僅僅是當做字符數組了,String 是一個完整的類型,并且有各種特性。我們先來看一下 String 的一個特性:substring。

簡單的看一下 String

首先粗略的了解一下字符串的實現。下面的代碼來自標準庫中 String.swift :

public struct String {
 public var _core: _StringCore
}

當然也有一些其他初始化設置,不過在聲明里只有這一個存儲屬性!秘密一定都在 StringCore.swift 里:

public struct _StringCore {
 public var _baseAddress: UnsafeMutableRawPointer?
 var _countAndFlags: UInt
 public var _owner: AnyObject?
}

在這個類型里還有很多其他東西,不過我們還是只關注存儲屬性:

  • Base address — 一個指向內部存儲的指針
  • Count — 字符串長度,UInt 類型,在一個 64 位的系統中,意味著有 62(64 - 2) 位的空間可以表示長度。這是一個非常大的數字。所以字符串的長度不太可能溢出。
  • Flags — 兩個 bits 用來做標志。第一位表示是否被 _StringBuffer 持有;第二位表示編碼格式是 ASCII 還是 UTF-16。

_StringCore 的真實情況比這里提到的要復雜的多,但是通過上面的內容可以讓我們更容易理解字符串的一些信息:字符串的內部存儲和存儲的大小(underlying storage and size)。

Substring

Swift 中要怎么創建一個 substring?最簡單的方式就是通過下標從 string 取一段:

let str = "Hello Swift!"
let slice = str[str.startIndex..
<str index="" str="" startindex="" nbsp="" offsetby:="" 5="" hello=""></str>

雖然很簡單,但是代碼看起來不太優雅。

String 的索引不是直觀的整型,所以截取時的位置索引需要利用 startIndex 和 index(_:offsetBy:)獲取。如果是從字符串開始位置截取,可以省略掉 startIndex :

let withPartialRange = str[..
<str index="" str="" startindex="" nbsp="" offsetby:="" 5="" still="" hello=""></str>

或者用 collection 中的這個方法:

let slice = str.prefix(5)
// still "Hello"

要記住字符串也是 collection ,所以你可以用集合下的方法,比如 prefix(),suffix(), dropFirst() 等。

Substring 的內部原理

substring 一個神奇的地方是他們重用了父 string 的內存。你可以把 substring 理解為父 string 的其中一段。

深入理解Swift中的Substring和String

舉個例子,如果從一個 8000 個字符的字符串中截取 100 個字符,并不需要重新初始化 100 個字符的內存空間。

這也意味著你可能不小心就把父 string 的生命周期延長了。如果有一大段字符串,然后你只是截取了一小段,只要截取的小段字符串沒有釋放,大段的字符串也不會被釋放。

Substring 內部到底是怎么做到的呢?

public struct Substring {
 internal var _slice: RangeReplaceableBidirectionalSlice
<string></string>

內部的 _slice 屬性保存著所有關于父字符串的信息:

// Still inside Substring
internal var _wholeString: String {
 return _slice._base
}
public var startIndex: Index { return _slice.startIndex }
public var endIndex: Index { return _slice.endIndex }

計算屬性 _wholeString(返回整個父字符串),startIndex 和 endIndex 都是通過內部的 _slice 返回。

也可以看出 slice 是如何引用父字符串的。

Substring 轉換為 String

最后代碼里可能有很多 substring,但是函數的參數類型需要的是 string。Substring 轉換到 string 的過程也很簡單:

let string = String(substring)

因為 substrings 和它的父字符串共享同一個內存空間,猜測創建一個新字符串應該會初始化一片新的存儲空間。那么 string 的初始化到底過程是怎樣的呢。

extension String {
 public init(_ substring: Substring) {
 // 1
 let x = substring._wholeString
 // 2
 let start = substring.startIndex
 let end = substring.endIndex
 // 3
 let u16 = x._core[start.encodedOffset..
<end encodedoffset="" nbsp="" 4a="" if="" start="" sameposition="" in:="" x="" unicodescalars="" end="" self="" 4b="" else=""></end>
  • 創建一個對原有父字符串的引用
  • 獲取 substring 在父字符串中的開始和結束位置
  • 獲取 UTF-16 格式的 substring 內容。_core 是 _StringCore 的一個實例。
  • 判斷匹配的 unicode 編碼,生成一個新的字符串實例

把 substring 轉換成 string 的步驟非常簡單,但是你可能要考慮是不是一需要這樣做。是不是進行 substring 操作的時候都要求類型是 string?如果對 substring 的操作都需要轉成 string,那么輕量級的 substring 也就失去了意義。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

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

AI

鲁山县| 大港区| 龙州县| 乳源| 天祝| 贵溪市| 宜州市| 钟山县| 芒康县| 云林县| 张家界市| 惠州市| 忻州市| 富川| 嘉禾县| 西城区| 石屏县| 宜昌市| 丹巴县| 葫芦岛市| 九寨沟县| 沧源| 建平县| 恩平市| 彰化市| 浙江省| 眉山市| 昌吉市| 板桥市| 察哈| 渭源县| 密云县| 佛学| 阿拉尔市| 牟定县| 于田县| 聂荣县| 通道| 九龙坡区| 文昌市| 丰台区|