日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

swift int转string_Swift集合类型协议浅析(下)

發布時間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 swift int转string_Swift集合类型协议浅析(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關注【搜狐技術產品】公眾號,第一時間獲取技術干貨

導讀

本篇是Swift集合類型協議淺析系列文章的下篇,在這篇文章中,我們將繼續圍繞集合類型協議展開討論,側重點更多地關注于String相關的周邊協議。

StringProtocol

代表一個字符串,這個字符串是由字符構成的集合,StringProtocol協議抽象了字符串的使用場景,比如uppercased()、lowercased()、comparable和collection等。在標準庫中,只有String和SubString類型遵循StringProtocol協議,可以直接使用==對SubString和String進行判斷,不需要類型轉換。

1let helloSwift = "Hello Swift" 2let swift = helloSwift[helloSwift.index(helloSwift.startIndex, offsetBy: 6)...] 3 4// comparing a substring to a string 5swift == "Swift" // true

也可以遍歷substring,或者從substring截取子字符串。在標準庫里也有一小部分函數使用StringProtocol類型作為參數。比如把一個字符串轉換為整型就是:init(text: StringProtocol)。雖然你可能不關心是string和substring,但是使用StringProtocol作為參數類型,調用者就不用進行類型轉換,對他們會友好很多。

CustomStringConvertible & CustomDebugStringConvertible

使用文本方式打印輸出對象是一個常見場景,Swift提供了多種方式:

  • print使用String(describing:)初始化;
  • debugPrint使用String(reflecting:);
  • dump使用Mirror(reflecting:)反射機制。

來看一個例子:

1struct BankCard {2 let bankName: String3 let cardNumber: Int4}5let bankcard = BankCard(bankName: "CBC",cardNumber: 123232324565)6// BankCard(bankName: "CBC", cardNumber: 123232324565)78extension BankCard: CustomStringConvertible {9 var description: String { 10 return "(self.bankName) (self.cardNumber)" 11 } 12} 13print(bankcard) 14// CBC 123232324565 1extension BankCard: CustomDebugStringConvertible { 2 var debugDescription: String { 3 return """ 4 BankName: (self.bankName) 5 CardNumber: (self.cardNumber) 6 """ 7} }

dump

1func dump<T>(_ value: T, name: String? = nil, indent: Int = 0, maxDepth: Int = .max, maxItems: Int = .max) -> T23/* * - T:是要打印的參數,是一個范型,也就是支持輸出各種類型 45* - name: 默認是空白,如果加上則會在打印內容前加入這個name67* - indent:縮進,默認是0,如果設置則會向前縮進相應的空白 89* - maxDepth:最大深度,默認全部打印,可以根據層級需要設置這個參數 10 11* - maxItems:最大條數,默認是全部打印,如果需要限制內容,可以設置這個參數 12 13 */ 1let names = ["apple", "orange", "banana"]2dump(names)34print(names)56let iPhones = ["iPhoneX": 9688, "iPhone8 plus": 7888, "iphone8": 6888]7dump(iPhones)89//輸出 10/* 11? 3 elements 12 - "apple" 13 - "orange" 14 - "banana" 15["apple", "orange", "banana"] 16? 3 key/value pairs 17 ? (2 elements) 18 - key: "iPhoneX" 19 - value: 9688 20 ? (2 elements) 21 - key: "iPhone8 plus" 22 - value: 7888 23 ? (2 elements) 24 - key: "iphone8" 25 - value: 6888 26*/
  • 打印log的時候,可以取代print,打印更詳細的內容;
  • 需要在控制臺打印數組或者字典的時候,用dump輸出的東西更立體,不會像print一樣打印出來是一行,對于特別大的數組或者字典很好用;
  • debug的時候能直接打印出對象的信息,我們debug的時候常常會打斷點,然后查看對象里的參數的值,用dump相當于把參數的那個界面全部展開并打印到了控制臺上。

LosslessStringConvertible

遵循此協議的類型,可以被轉換為String,同時與此相反,可以再從String轉換回原始類型,沒有任何信息丟失;

協議的繼承關系如上圖所示,很多系統類型已經實現了LosslessStringConvertible,所以才能與String之間互相轉換,如Int、Int8、Int32、Int64、Bool、Character、Double、Float等。

遵循協議需要實現init?(_ description: String)和description。

1extension FlightCode: LosslessStringConvertible {2 public init?(_ description: String) {3 let components = description.split(separator: " ")4 guard components.count == 2,5 let airlineCode = components.first,6 let number = components.last,7 let flightNumber = Int(number)8 else {9 return nil 10 } 11 self.airlineCode = String(airlineCode) 12 self.flightNumber = flightNumber 13 } 14} 15let flight = FlightCode(airlineCode: "AA", 16 flightNumber: 1) 17 18String(flight) 19// "AA 1" 20 21FlightCode(String(flight)) 22// FlightCode(airlineCode: "AA", flightNumber: 1)

ExpressibleByUnicodeScalarLiteral,ExpressibleByExtendedGraphemeClusterLiteral,ExpressibleByStringLiteral

String字面量使用引號表示,當封閉的值包含單個字符集群時,同樣的語法也可以表示字符集群文字;當封閉的值包含單個字符值時,同樣的語法也可以表示Unicode標量文字。

1// ExpressibleByUnicodeScalarLiteral 2let unicodeScalar: Unicode.Scalar = "A" 3 4// ExpressibleByExtendedGraphemeClusterLiteral 5let character: Character = "A" 6 7// ExpressibleByStringLiteral 8let string: String = "A"

可擴展的字形集群

每一個Swift的Character類型實例都表示了單一的擴展字形集群。擴展字形集群是一個或者多個有序的Unicode標量(當組合起來時)產生的單個人類可讀字符。舉例來說,字母é以單個Unicode標量é(LATIN SMALL LETTER E WITH ACUTE,或者U+00E9)表示。總之,同樣的字母也可以用一對標量——一個標準的字母e(LATINSMALL LETTER E,或者說U+0065),以及COMBINING ACUTE ACCENT標量(U+0301)表示。COMBINING ACUTE ACCENT標量會以圖形方式應用到它前邊的標量上,當Unicode文本渲染系統渲染時,就會把e轉換為é來輸出。

在這兩種情況中,字母é都會作為單獨的Swift Character值以擴展字形集群來表示。在前者中,集群包含了一個單獨的標量;后者,則是兩個標量的集群。

1let eAcute: Character = "u{E9}" // é 2let combinedEAcute: Character = "u{65}u{301}" // e followed by 3// eAcute is é, combinedEAcute is é

擴展字形集群是一種非常靈活的把各種復雜腳本字符作為單一Character值來表示的方法。比如說韓文字母中的音節能被表示為復合和分解序列兩種,這兩種表示在Swift中都完全合格于單一Character值:

1let precomposed: Character = "u{D55C}" // ? 2let decomposed: Character = "u{1112}u{1161}u{11AB}" // ?, ?, ? 3// precomposed is ?, decomposed is ?

繼承關系:

所以初始化一個Unicode.Scalar通過包含多個scalar標量的字面量,或者多個字符字面量期望轉成一個字符,都會失敗。

1("ABC" as Unicode.Scalar) // Error 2("ABC" as Character) // Error

通過字面量初始化特定類型

1extension URL: ExpressibleByStringLiteral {2 public init(stringLiteral value: String) {3 guard let url = URL(string: "(value)") else {4 preconditionFailure("This url: (value) is not invalid")5 }6 self = url7 }8}9 10let url:URL = "https://www.baidu.com" 11 12print(url) 13 14//let urls = URL.init(string: "https://www.baidu.com")

上面這個例子擴展了URL類型,使其能夠直接通過String字面量轉換為URL,十分簡潔,但是這種方式也有其弊端,開發中容易引起歧義。

ExpressibleByStringInterpolation

字符串插值是Swift5的新特性;通常,字符串文字中的內插值被轉換為字符串,使用String(describing:);通過遵循ExpressibleBy

StringInterpolation協議(這個協議繼承ExpressibleByStringLiteral),這個類型可以定義StringInterpolation通過字面量改變插值行為。

ExpressibleByStringLiteral

三個方法需要實現:

1init(stringLiteral value: String) 2init(extendedGraphemeClusterLiteral value: String) 3init(unicodeScalarLiteral value: String)

ExpressibleByStringInterpolation

1init(stringInterpolation: StringInterpolation)

要讓一個類型遵循ExpressibleByStringInterpolation,最基本的你需要:

  • 讓這個類型擁有一個類型為StringInterpolation的子類型,這個子類型遵循StringInterpolationProtocol并將負責解釋插值;
  • 這個子類型僅需要實現appendLiteral(_ literal: String)方法,再選擇一個或多個你自己想要支持的appendInterpolation(...)簽名的方法;
  • 這個StringInterpolation子類型會作為“構造器”服務于你的主類型,然后編譯器會調用那些append…方法一步一步地構造對象;
  • 然后你的主類型需要實現init(stringInterpolation: StringInterpolation),它會用上一步的結果來實例化它自己。

你可以實現任何你喜歡的appenInterpolation(...)方法,這意味著你可以任意選擇支持什么插值。這是一個帶來巨大的可能性的超強功能。

舉個例子,如果你實現了func appendInterpolation(_ string: String, pad: Int),那么意味著你將可以用類似這樣的插值:"Hello (name, pad: 10), how are you?"來構造你的類型。插值只需要匹配你的StringInterpolation子類型其中一個支持的appendInterpolation方法簽名。

參考:

[1].https://swift.gg/2019/04/22/swift5-stringinterpolation-part1/

[2].https://academy.realm.io/cn/posts/try-swift-soroush-khanlou-sequence-collection/

[3].https://swift.gg/2017/02/20/why-is-dictionary-not-a-mutablecollection/


狐友技術團隊其他精彩文章

Swift集合類型協議淺析(上)

分布式追蹤系統概述及主流開源系統對比

不了解GIF的加載原理?看我就夠了!

安卓系統權限,你真的了解嗎?

Swift之Codable實戰技巧


加入搜狐技術作者天團,千元稿費等你來!

獲取更多資訊請關注微信公眾號【搜狐技術產品】,微信后臺聯系搜狐技術產品小助手。

總結

以上是生活随笔為你收集整理的swift int转string_Swift集合类型协议浅析(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。