精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊聊Swift 中 key paths 的能力

開發 前端
Swift 不斷獲取越來越多的更具動態性的功能,同時還一直把它的關注點放在代碼的類型安全上。其中的一個特性就是 KeyPath。

[[409895]]

前言

自從 swift 剛開始就被設計為是編譯時安全和靜態類型后,它就缺少了那種我么經常在運行時語言中的動態特性,比如 Object-C, Ruby 和 JavaScript。舉個例子,在 Object-C 中,我們可以很輕易的動態去獲取一個對象的任意屬性和方法 - 甚至可以在運行時交換他們的實現。

雖然缺乏動態性正是 Swift 如此強大的一個重要原因 - 它幫助我們編寫更加可以預測的代碼以及更大的保證了代碼編寫的準確性�, 但是有的時候,能夠編寫具有動態特性的代碼是非常有用的。

值得慶幸的是,Swift 不斷獲取越來越多的更具動態性的功能,同時還一直把它的關注點放在代碼的類型安全上。其中的一個特性就是 KeyPath。這周,就讓我們來看看 KeyPath 是如何在 Swift 中工作的,并且有哪些非??岱浅S杏玫氖虑榭梢宰屛覀內プ?。

基礎

key paths 基本上讓我們將任何實例屬性引用為單獨的值。因此,它們可以通過表達式傳遞,并使一段代碼能夠獲取或設置一個屬性而無需實際了解該屬性。

Key paths 有三種主要變種:

  • KeyPath:提供對屬性的只讀訪問權限。
  • WritableKeyPath: 提供對具有值語義的可變屬性的讀寫訪問權限(因此所討論的實例也需要是可變的,以便允許的寫入)。
  • ReferenceWritableKeyPath: 只能與引用類型(例如類的實例)一起使用,并為任何可變屬性提供讀寫訪問權限。

還有一些額外的 key paths 類型,即可以減少內部代碼復制并幫助類型擦除,但我們將專注于本文中的主要類型。

讓我們深入查看如何使用 key paths,是什么讓他們有趣和潛在的強大。

功能表達

假設我們正在構建一個應用程序,讓用戶讀取來自 Web 的文章,并且我們有一個用來代表一個這樣的文章的 Article 模型,看起來像這樣:

  1. struct Article { 
  2.     let id: UUID 
  3.     let source: URL 
  4.     let title: String 
  5.     let body: String 

每當我們使用這些模型的數組時,希望從每個型號中提取一個數據來形成一個新數組 —— 例如在以下兩個示例中,我們正在收集所有 ID 和所有文章的來源:

  1. let articleIDs = articles.map { $0.id } 
  2. let articleSources = articles.map { $0.source } 

雖然上面完全有效,因為我們僅僅對從每個實例提取單個值有興趣,但我們真的不需要閉包的全部能力,因此使用 key paths 可能非常適合。

我們將首先擴展 Sequence 來添加 map 的重載,該 map 采用 key paths 而不是閉包。由于我們只對此用例的只讀屬性訪問感興趣,因此我們將使用標準的 KeyPath,并且實際執行數據提取,我們將使用與給定鍵路徑的子項作為參數使用,如下所示:

  1. extension Sequence { 
  2.     func map<T>(_ keyPath: KeyPath<Element, T>) -> [T] { 
  3.         return map { $0[keyPath: keyPath] } 
  4.     } 
  • 注意:如果您使用的 Swift 5.2 或更高版本,則不再需要上述擴展,因為現在可以將 key paths 自動轉換為函數。

通過以上擴展,我們現在能夠使用一個非常好的和簡單的語法來從任何序列中的每個元素中提取單個值,使得可以從之前轉換我們的示例:

  1. let articleIDs = articles.map(\.id) 
  2. let articleSources = articles.map(\.source) 

這是非常酷的,但是,當 key paths 真正開始發光時,它們用于形成稍微復雜的表達式,例如在排序一系列值時。

標準庫能夠自動對包含 Sortable 元素的任何序列進行排序,但對于所有其他類型,我們必須提供自己的排序閉包。但是,使用 key paths,我們可以通過基于 Comparable 的 key patsh 輕松添加用于對任何序列進行排序的支持。就像之前一樣,我們將在序列 Sequence 協議中添加一個擴展,將給定 key paths 轉換為排序表達式閉包:

  1. extension Sequence { 
  2.     func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] { 
  3.         return sorted { a, b in 
  4.             return a[keyPath: keyPath] < b[keyPath: keyPath] 
  5.         } 
  6.     } 

使用上面的擴展,我們現在能夠快速且輕松地對任何序列進行排序,只需給出我們想要排序的 key paths。如果我們正在構建任何形式的可排序列表的應用程序 —— 例如包含播放列表的音樂應用程序 —— 這非常方便,因為我們現在自由地對我們的列表進行排序,甚至是嵌套的):

  1. playlist.songs.sorted(by: \.name
  2. playlist.songs.sorted(by: \.dateAdded) 
  3. playlist.songs.sorted(by: \.ratings.worldWide) 

這樣做的似乎只是簡單地添加了一個語法糖,但可以制作一些更復雜的代碼處理的序列同時更容易閱讀,并且還可以幫助減少代碼復制,因為我們現在能夠為任何屬性重用相同的排序代碼。

不需要實例

雖然適量的語法糖很好,但是關鍵路徑的真正的威力來自于,它可以讓我們引用屬性而不必與任意的實例相關聯。延續使用之前的音樂主題,假設我們正在開發一個展示歌曲列表的 App - 并且在 UI 中為這個列表配置 UITableViewCell,我們使用如下的配置類型:

  1. struct SongCellConfigurator { 
  2.     func configure(_ cell: UITableViewCell, for song: Song) { 
  3.         cell.textLabel?.text = song.name 
  4.         cell.detailTextLabel?.text = song.artistName 
  5.         cell.imageView?.image = song.albumArtwork 
  6.     } 

再次聲明,上面的代碼沒有一點問題,但是我們期望以這樣的方式渲染其他的模型的概率非常的高(非常多的 tableView 的 cells 嘗試著去渲染標題,副標題以及圖片而不用去管他們代表的是什么模型)- 因此讓我們看看,我們能否用關鍵路徑的威力去創建一個共享的配置實現,讓他可以被任意的模型使用。

讓我們創建一個名叫 CellConfigurator 的泛型,然后因為我們想要用不同的模型去渲染不同的數據,所以我們將會給它提供一組基于關鍵路徑的屬性 - 我們先渲染其中的一個數據:

  1. struct CellConfigurator<Model> { 
  2.     let titleKeyPath: KeyPath<Model, String> 
  3.     let subtitleKeyPath: KeyPath<Model, String> 
  4.     let imageKeyPath: KeyPath<Model, UIImage?> 
  5.  
  6.     func configure(_ cell: UITableViewCell, for model: Model) { 
  7.         cell.textLabel?.text = model[keyPath: titleKeyPath] 
  8.         cell.detailTextLabel?.text = model[keyPath: subtitleKeyPath] 
  9.         cell.imageView?.image = model[keyPath: imageKeyPath] 
  10.     } 

上面的實現優雅的地方在于,我們現在可以為每個模型定制我們的 CellConfigurator,使用相同的輕量的關鍵路徑語法,如下所示:

  1. let songCellConfigurator = CellConfigurator<Song>( 
  2.     titleKeyPath: \.name
  3.     subtitleKeyPath: \.artistName, 
  4.     imageKeyPath: \.albumArtwork 
  5.  
  6. let playlistCellConfigurator = CellConfigurator<Playlist>( 
  7.     titleKeyPath: \.title, 
  8.     subtitleKeyPath: \.authorName, 
  9.     imageKeyPath: \.artwork 

就像標準庫中的 map 和 sorted 等函數的操作一樣,我們曾經可能會使用閉包去實現 CellConfigurator。然而,通過關鍵路徑,我們能夠使用一個非常好的語法去實現它 - 并且我們也不需要任何的訂制化的操作去不得不通過模型實例去處理 - 使它們變得更加的簡單,更加的具有說服力。

轉化為函數

目前為止,我們僅僅使用關鍵路徑來讀取值 - 現在讓我們看看我們如何使用它們來動態的寫值。在很多不同的代碼中,我們常常可以見到一些像下面的代碼一樣的列子 - 我們通過這段代碼來加載一系列的事項,然后在 ListViewController 中去渲染它們,然后當加載操作完成后,我們會簡單的將加載的事項賦值給視圖控制器中的屬性。

  1. class ListViewController { 
  2.     private var items = [Item]() { didSet { render() } } 
  3.  
  4.     func loadItems() { 
  5.         loader.load { [weak self] items in 
  6.             self?.items = items 
  7.         } 
  8.     } 

讓我們看看,通過關鍵路徑賦值能否讓上面的語法簡單一點,并且能夠移除我們經常使用的 weak self 的語法(如果我們忘記對 self 的引用前加上 weak 關鍵字的話,那么就會產生循環引用)。

既然所有上面我們做的事情都是獲取傳遞給我們閉包的值,并將它賦值給視圖控制器中的屬性 - 那么如果我們真的能夠將屬性的 setter 作為函數傳遞,會不會很酷呢?這樣我們就可以直接將函數作為完成閉包傳遞給我們的加載方法,然后所有的事情都會正常執行。

為了實現這一目標,首先我們先定義一個函數,讓任意的可寫的轉化為一個閉包,然后為關鍵路徑設置屬性值。為此,我們將會使用 ReferenceWritableKeyPath 類型,因為我們只想把它限制為引用類型(否則的話,我們只會改變本地屬性的值)。給定一個對象,以及給這個對象設置關鍵路徑,我們將會自動將捕獲的對象作為弱引用類型,一旦我們的函數被調用,我們就會給匹配關鍵路徑的屬性賦值。就像這樣:

  1. func setter<Object: AnyObject, Value>( 
  2.     for object: Object, 
  3.     keyPath: ReferenceWritableKeyPath<Object, Value> 
  4. ) -> (Value) -> Void { 
  5.     return { [weak object] value in 
  6.         object?[keyPath: keyPath] = value 
  7.     } 

使用上面的代碼,我們可以簡化之前的代碼,將弱引用的 self 去除,然后用看起來非常簡潔的語法結尾:

  1. class ListViewController { 
  2.     private var items = [Item]() { didSet { render() } } 
  3.  
  4.     func loadItems() { 
  5.         loader.load(then: setter(for: self, keyPath: \.items)) 
  6.     } 

非??嵊袥]有!或許它還能變得更加的酷,當上面的代碼跟更加先進的函數式編程思想結合在一起的時候,如組合函數 - 因此我們現在可以將多個 setter 函數和其他的函數鏈接在一起使用。在接下來的文章中,我們將介紹函數式編程和組合函數。

總結

首先,看起來如何以及何時去使用 swift 關鍵路徑這樣的功能有點困難,并且很容易將它們看做是簡單的語法糖。能夠使用更加動態的方法去引用屬性是一件非常強大的事情,即使閉包通常可以做很多類似的事情,但是輕量的語法以及關鍵路徑的聲明,都使他們能夠成為處理非常多種類的數據的好的匹配。

 

責任編輯:姜華 來源: Swift社區
相關推薦

2022-05-11 09:01:54

Swift類型系統幻象類型

2022-07-04 08:54:39

Swift處理器項目

2022-06-13 09:02:06

Swift類型占位符

2022-05-25 09:15:01

Swift 5.6占位符

2021-07-15 16:41:21

Swift查詢函數

2021-11-17 08:11:35

MySQL

2021-08-31 07:54:24

SQLDblink查詢

2024-04-26 00:00:00

Rust檢查器代碼

2023-11-09 11:56:28

MySQL死鎖

2023-12-18 07:32:08

ChatGPTLLMCoT

2023-07-28 09:54:14

SQL數據Excel

2021-03-08 00:11:02

Spring注解開發

2024-04-15 00:00:00

RabbitMQ死信隊列消息

2022-08-03 08:11:58

數據測試同類型

2021-09-03 06:46:34

SQL分組集功能

2021-08-16 08:12:04

SQLMerge用法

2021-10-30 19:56:10

Flutter按鈕 Buttons

2023-08-29 09:46:12

SQLCTE遞歸

2021-12-11 19:00:54

Java中斷機制

2021-08-16 06:56:21

Slice數組類型內存
點贊
收藏

51CTO技術棧公眾號

国产精品不卡一区二区三区| 久久国产精品成人免费观看的软件| 亚洲www啪成人一区二区麻豆| 麻豆av一区| 中文字幕在线观看高清| 婷婷激情综合| 欧美一级专区免费大片| 99精品视频播放| 91高清在线视频| 国产一区不卡在线| 97色伦亚洲国产| 久久久精品人妻无码专区| 朝桐光一区二区| 亚洲精品一二三区| 免费在线观看91| 在线视频 91| 午夜精品国产| 亚洲欧美在线一区二区| 亚洲欧美日本一区二区三区| caoprom在线| 国产亚洲精久久久久久| 91高跟黑色丝袜呻吟在线观看| 国产无遮挡aaa片爽爽| 欧美一区二区三| 日韩你懂的在线播放| 欧美成人精品欧美一级乱| 黄色小网站在线观看| 91丨porny丨在线| 国产综合久久久久| 波多野结衣国产| 91九色精品| 精品视频www| 午夜大片在线观看| 另类图片综合电影| 国产精品久久久久久久久免费丝袜| 成人欧美一区二区| 在线视频你懂得| 中国女人久久久| 欧美成人免费播放| 国产性猛交xx乱| 欧美激情网址| 日韩一级在线观看| www.com黄色片| 在线观看涩涩| 亚洲国产精品欧美一二99| 亚洲高清视频一区二区| 亚洲欧洲国产综合| 国产成人啪午夜精品网站男同| 国产精品入口日韩视频大尺度| 国产精品日日夜夜| 综合视频在线| 中文字幕亚洲精品| 日韩中文字幕电影| 女人抽搐喷水高潮国产精品| 欧美一区二区视频在线观看2020| 污污视频网站免费观看| 神马午夜在线视频| 精品久久久久久国产| 黄网站色视频免费观看| 很黄的网站在线观看| 国产精品久久久一本精品| 欧美少妇一区| 日av在线播放| 91视视频在线观看入口直接观看www | 国产成人精品999在线观看| 欧美成人午夜电影| 手机看片国产精品| 亚洲福利影视| 欧美电影在线免费观看| 久久国产精品国产精品| 欧美激情福利| 欧美日韩精品系列| 日本高清久久久| 国产亚洲人成a在线v网站 | 中文字幕亚洲色图| 亚洲精品国产熟女久久久| 蜜桃a∨噜噜一区二区三区| 日韩国产欧美区| 深爱五月激情网| 九九视频免费观看视频精品| 亚洲乱码一区二区| 国产传媒第一页| 美女少妇全过程你懂的久久 | 日本精品性网站在线观看| 青青草成人av| 模特精品在线| 国产精品久久久久久亚洲调教| 国产精品第6页| 免费观看在线综合| 欧美一区二区在线视频| 超碰97人人射妻| 美女100%一区| 精品视频一区三区九区| 五月花丁香婷婷| 香蕉大人久久国产成人av| 波多野结衣的一区二区三区 | 亚洲精品视频网| 亚洲瘦老头同性70tv| 亚洲精品在线不卡| 日本污视频网站| 91精品福利| 午夜精品福利视频| 亚洲综合成人av| 精一区二区三区| 高清不卡日本v二区在线| 午夜视频在线免费播放| 国产精品丝袜黑色高跟| 在线观看成人免费| 国产蜜臀一区二区打屁股调教| 五月激情丁香一区二区三区| www.日日操| 国产精品igao视频网网址不卡日韩| 精品人伦一区二区色婷婷| ass精品国模裸体欣赏pics| 日韩伦理视频| 久久久久久成人| 国产三级理论片| 成人性生交大片免费看中文网站| 日韩亚洲不卡在线| av小说在线播放| 欧美日韩精品三区| 在线免费播放av| 日韩精品水蜜桃| 8x海外华人永久免费日韩内陆视频| 97av免费视频| 久久综合色婷婷| 黄色录像特级片| 91久久久久久白丝白浆欲热蜜臀| 欧美成人在线直播| 男人天堂资源网| 国产美女一区| 国产精品jizz视频| 黄网站视频在线观看| 色婷婷精品大在线视频| 少妇极品熟妇人妻无码| 日韩国产一区二区| 欧洲一区二区视频| 成人毛片视频免费看| 中文字幕五月欧美| 九九九在线观看视频| 日本亚洲不卡| 国语自产精品视频在线看一大j8 | 免费在线超碰| 亚洲午夜精品久久久久久久久| 超碰超碰在线观看| 黑人操亚洲人| 欧美夜福利tv在线| 日本激情一区二区三区| 亚洲综合男人的天堂| 丰满饥渴老女人hd| 综合视频在线| 99电影网电视剧在线观看| 伦理片一区二区三区| 亚洲成人av一区| 国内av免费观看| 婷婷综合五月| 91久久嫩草影院一区二区| 中文日本在线观看| 欧美日韩小视频| 美国美女黄色片| 蜜臀av一区二区在线免费观看| 色99中文字幕| 日本另类视频| 中文字幕在线看视频国产欧美在线看完整| 亚洲天堂男人av| 久久先锋影音av| 别急慢慢来1978如如2| 五月天亚洲色图| 久久久久久91香蕉国产| 天堂v在线观看| 午夜精品久久久久久久久久| 欧美日韩人妻精品一区在线| 日韩一级不卡| 久久久久国产精品视频| 亚洲精品中文字幕| 亚洲欧洲激情在线| 日批视频免费观看| 中文字幕在线观看不卡| 国产黑丝在线视频| 国内精品美女在线观看| 精品无码久久久久国产| 成人爱爱网址| 中文字幕一区二区精品| 国产麻豆一精品一男同| 亚洲国产欧美在线人成| av直播在线观看| 奇米色777欧美一区二区| 亚洲一区三区电影在线观看| 精品精品视频| 91极品视频在线| 国产小视频福利在线| 欧美私人免费视频| 日本福利片在线观看| 国产成人精品一区二| 国产伦精品一区二区三区四区视频_| 网友自拍区视频精品| 国产噜噜噜噜噜久久久久久久久| 亚洲性图自拍| 亚洲精品视频免费| 国产永久免费视频| 亚洲va在线va天堂| 一级在线观看视频| 国产精品综合一区二区三区| 欧美日韩性生活片| 欧美一区二区三区激情视频| 亚洲影院污污.| 中文在线免费二区三区| 最新国产成人av网站网址麻豆| 亚洲国产999| 在线免费亚洲电影| 国产一二三四在线| 亚洲国产精品精华液2区45| 日韩成人av影院| 亚洲精选久久| 久久免费99精品久久久久久| 久久精品资源| 久久久视频在线| 福利在线播放| 精品国产免费视频| 69视频免费看| 亚洲专区一二三| 中字幕一区二区三区乱码| 狠狠色丁香九九婷婷综合五月| 免费看日本黄色| 偷拍一区二区| 3d动漫啪啪精品一区二区免费| 日本在线影院| 欧美xxxx18性欧美| yw视频在线观看| 亚洲国产精品成人av| 国产乱淫片视频| 欧洲亚洲精品在线| 日韩欧美a级片| 亚洲六月丁香色婷婷综合久久| 中文字幕一区二区三区人妻不卡| 国产99久久久久久免费看农村| 亚洲激情在线看| 日韩中文字幕区一区有砖一区| 亚洲中文字幕无码av永久| 亚洲欧美综合久久久| 日韩在线导航| 美女毛片一区二区三区四区| 久久精品国产美女| 97视频一区| 亚洲自拍偷拍视频| 成人自拍av| 2019中文字幕在线观看| 黄色影院在线看| 久久成年人免费电影| av中文字幕在线播放| 色黄久久久久久| 成人精品一区二区三区免费| 亚洲色图美腿丝袜| 日夜干在线视频| 日韩av网站导航| 熟妇高潮一区二区三区| 亚洲国产精品字幕| 欧美性受xxxx狂喷水| 精品福利二区三区| 国产91免费在线观看| 欧美哺乳videos| 日韩一级片免费观看| 精品不卡在线视频| 国产综合在线播放| 亚洲精品一区二区三区蜜桃下载 | 四虎成人免费影院| 国产精品水嫩水嫩| 日韩在线一卡二卡| 1000精品久久久久久久久| 亚洲欧洲综合网| 中文字幕亚洲精品在线观看| 亚洲天堂一级片| 亚洲激情六月丁香| 国语对白一区二区| 欧美日韩一区二区精品| av片免费观看| 欧美在线播放高清精品| 伊人久久国产精品| 欧美久久一二三四区| 99视频国产精品免费观看a| 日韩视频一区二区在线观看| 手机看片一区二区| 亚洲美女视频网| 日韩成人影视| 欧美日韩高清在线观看| 欧美aa在线| 国产精品成人品| 日韩欧美激情电影| 欧美激情第一页在线观看| 欧美日韩国产免费观看视频| 中文字幕第一页亚洲| 欧美日一区二区三区在线观看国产免| 日本福利视频一区| 日韩二区三区在线观看| 手机版av在线| 成+人+亚洲+综合天堂| 五月天精品视频| 亚洲欧洲在线观看av| 国产真实乱偷精品视频| 色av综合在线| 国产露脸91国语对白| 亚洲精品美女视频| 里番在线观看网站| 国内外成人免费激情在线视频网站 | 91免费版在线| 欧美xxxx精品| 亚洲永久免费视频| 天天干天天插天天射| 日韩欧美国产综合一区 | 经典三级一区二区| 999日本视频| av伊人久久| 成人精品视频在线播放| 麻豆国产欧美日韩综合精品二区 | 亚洲精品在线影院| 福利精品视频| 久久日文中文字幕乱码| 男人日女人bb视频| 国产精品一区二区男女羞羞无遮挡| 香蕉网在线播放| 亚洲黄网站在线观看| а中文在线天堂| 日韩成人av在线| www国产在线观看 | 四虎在线精品| 久久精品人成| 黄色国产精品| 国产精品嫩草影院8vv8| 91蜜桃婷婷狠狠久久综合9色| 久草视频手机在线| 欧美视频三区在线播放| 天堂在线资源网| 欧美成人高清视频| 欧美天堂一区二区| 蜜桃传媒一区二区| 国内久久视频| 免费欧美一级片| 国产精品成人免费在线| 日本熟妇一区二区三区| 亚洲精品一区二区三区蜜桃下载| 含羞草www国产在线视频| 国产mv免费观看入口亚洲| 欧美精品密入口播放| 日韩精品一区二区免费| 精品一区二区三区在线观看| 青青草华人在线视频| 91成人国产精品| 久久精品视频免费| 亚洲v在线观看| 亚洲视频香蕉人妖| 在线视频播放大全| 少妇高潮久久久久久潘金莲| 欧美日韩视频网站| 狼狼综合久久久久综合网| 激情丁香综合| 国产高潮失禁喷水爽到抽搐| 一区二区三区在线观看网站| 国产偷拍一区二区| 另类专区欧美制服同性| 精品视频在线观看免费观看| 欧美aaa在线观看| 国产一区二区免费在线| 久久爱一区二区| 欧美丰满少妇xxxbbb| 免费在线看黄网站| 成人精品一区二区三区电影黑人| 91精品国产福利在线观看麻豆| 亚洲天堂网2018| 亚洲欧洲综合另类在线| 99精品在线视频观看| 欧美精品在线免费播放| 亚洲精品观看| 无码专区aaaaaa免费视频| av网站免费线看精品| 五月婷婷亚洲综合| 国产一区二区三区欧美| 欧美激情福利| 精品一二三四五区| 91香蕉视频污| 中文字幕 亚洲视频| 久久伊人精品视频| 欧美视频精品全部免费观看| 日本阿v视频在线观看| gogo大胆日本视频一区| 青青青国产在线| 尤物九九久久国产精品的分类| 日本h片久久| 自拍偷拍99| 国产成人超碰人人澡人人澡| 中文字幕一区二区三区精品| 精品国产sm最大网站免费看| videos性欧美另类高清| 亚洲欧美一区二区原创| 国产成人综合亚洲网站| 一区二区三区视频免费看| 伊人青青综合网站| 亚州一区二区| 熟妇人妻无乱码中文字幕真矢织江| 亚洲精品久久嫩草网站秘色| 色wwwwww|