[编程开发] Swift能否算的上趋近于完美的语言?

[复制链接]
性请所次 发表于 2023-10-4 19:17:12|来自:北京 | 显示全部楼层 |阅读模式
本人熟悉Go和Rust,最近迷上了Swift。
1.语法:Swift的语法介于Go和Rust之间,和两者非常相似,上手很快,抽象能力也很强;
2.性能:Go有GC,不适用于性能敏感的部分;Rust无GC,性能强劲;Swift也无GC,完全适用于无延迟场景;
3.学习难度:Go很简单,Rust太复杂,Swift比Go复杂一点,但是比Rust简单太多
综上所述,Swift在难易度和性能之间的平衡性达到了最佳平衡,这是否趋近于完美??
全部回复5 显示全部楼层
cyx1689 发表于 2023-10-4 19:18:07|来自:北京 | 显示全部楼层
前言

我最喜欢 Swift 语言的一个特性是动态成员查找(dynamic member lookup)。虽然我们并不经常使用它,但它通过改进我们访问特定类型数据的方式,显著改善了所提供类型的 API。
Glassfy:简化构建、管理和推广应用内购买。从订阅管理 SDK 到付费墙等完整的货币化工具。立即免费构建。
基础知识

假设我们正在开发一个提供缓存功能的类型,并将其建模为名为 Cache 的结构体。
  1. struct Cache {
  2.     var storage: [String: Data] = [:]
  3. }
复制代码
为了访问缓存的数据,我们调用存储属性的下标,该存储属性是 Dictionary 类型提供的。
  1. var cache = Cache()
  2. let profile = cache.storage["profile"]
复制代码
在这里没有什么特别之处。我们像以前一样通过 Dictionary 类型的下标访问字典。让我们看看如何使用 @dynamicMemberLookup 属性改进 Cache 类型的 API。
  1. @dynamicMemberLookup
  2. struct Cache {
  3.     private var storage: [String: Data] = [:]
  4.     subscript(dynamicMember key: String) -> Data? {
  5.         storage[key]
  6.     }
  7. }
复制代码
如上例所示,我们使用 @dynamicMemberLookup 属性标记了 Cache 类型。我们必须实现具有 dynamicMember 参数并返回我们需要的任何内容的下标。
  1. var cache = Cache()
  2. let profile = cache.profile
复制代码
现在,我们可以更方便地访问 Cache 类型的配置文件数据。我们的 API 的使用者可能会认为配置文件是 Cache 类型的属性,但事实并非如此。
此特性完全在运行时工作,并利用了在点符号后键入的任何属性名称来访问 Cache 类型的下标,该下标具有 dynamicMember 参数。
整个逻辑在运行时运行,编译期间的结果是不确定的。在运行时,您完全可以决定应该从下标返回哪些数据以及如何处理 dynamicMember 参数。
使用 KeyPath 的编译时安全性

我们唯一能找到的缺点是缺乏编译时安全性。我们可以将 Cache 类型视为代码中键入的任何属性名称。幸运的是,@dynamicMemberLookup 下标的参数不仅可以是 String 类型,还可以是 KeyPath 类型。
  1. @dynamicMemberLookup
  2. final class Store\<State, Action>: ObservableObject {
  3. typealias ReduceFunction = (State, Action) -> State
  4.     @Published private var state: State
  5.     private let reduce: ReduceFunction
  6.     init(
  7.         initialState state: State,
  8.         reduce: @escaping ReduceFunction
  9.     ) {
  10.         self.state = state
  11.         self.reduce = reduce
  12.     }
  13.     subscript<T>(dynamicMember keyPath: KeyPath<State, T>) -> T {
  14.         state[keyPath: keyPath]
  15.     }
  16.     func send(_ action: Action) {
  17.         state = reduce(state, action)
  18.     }
  19. }
复制代码
如上例所示,我们定义了接受强类型 KeyPath 实例的 dynamicMember 参数下标。在这种情况下,我们允许 State 类型的 KeyPath,这有助于我们获得编译时安全性。因为每当我们传递与 State 类型无关的错误 KeyPath 时,编译器都会显示错误。
  1. struct State {
  2. var products: \[String] = \[]
  3. var isLoading = false
  4. }
  5. enum Action {
  6. case fetch
  7. }
  8. let store: Store\<State, Action> = .init(initialState: .init()) { state, action in
  9. var state = state
  10. switch action {
  11. case .fetch:
  12. state.isLoading = true
  13. }
  14. return state
  15. }
  16. print(store.isLoading)
  17. print(store.products)
  18. print(store.favorites) // Compiler error
复制代码
在上例中,我们通过接受 KeyPath 的下标访问 Store 的私有 state 属性。这看起来与前面的例子类似,但在这种情况下,只要您尝试访问 State 类型的不可用属性,编译器就会显示错误。
总结

今天我们学习了如何使用 @dynamicMemberLookup 属性改进特定类型的 API。虽然并不是每个类型都需要它,但您可以谨慎使用它来改善 API。
flyren 发表于 2023-10-4 19:18:56|来自:北京 | 显示全部楼层
JAVA:我流行因为我开放。
Swift:我流行因为我优雅。
C#:哎...
meiya121 发表于 2023-10-4 19:19:27|来自:北京 | 显示全部楼层
Swift是一个在Apple强控制下的语言,Swift之父都受不了走人了
单看语法特性,Swift确实是目前最好的,因为语言是2014年才发布的,并且经过了几次ABI不兼容的版本升级,能加的语法特性都加了
但是生态这东西,你管控多了,自然愿意陪你玩的人就少了,很多本来很有人气的库也会慢慢因为版本兼容问题废弃了
cyj920 发表于 2023-10-4 19:20:17|来自:北京 | 显示全部楼层
有这个趋势,现在swift在别的编辑器中直接写服务端,还挺好用的了
shzlq 发表于 2023-10-4 19:21:15|来自:北京 | 显示全部楼层
接触使用过Objective-C,C,C++,Java,JavaScript,Python以及Swift。单纯从语言的角度确实最喜欢Swift。首先它比类C系列语言以及Java更加现代,表达能力更强。其次相比于js和Python强类型带来的可读性和可维护性也更加适用于大型项目。另外由于苹果的强势,所以Swift没有无法解决的历史问题,可以随心所欲的搞break change从而让语言始终处于最佳状态,这也是它的优点。

快速回帖

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则