Swift基础

【Swift进阶笔记】泛型

2022-03-02  本文已影响0人  BeethOven
image.png

泛型类型

可选类型是泛型

 enum Optional<Wrapped>  {
    case none
    case some(Wrapped)
}

Array, Dictionary, Set也是泛型,如果不指定类型,系统默认为Any类型

@frozen public struct Array<Element> {
}

@frozen public struct Dictionary<Key, Value> where Key : Hashable {
}

@frozen public struct Set<Element> where Element : Hashable {
}

var arr = ["1", 2] as [Any]

扩展类型泛型

enum BinaryLeef<Element> {
    case leaf
    indirect case node(Element, l: BinaryLeef<Element>, r: BinaryLeef<Element>)
}

extension BinaryLeef {
    init(_ value: Element) {
        self = .node(value, l: .leaf, r: .leaf)
    }
}
extension BinaryLeef {
    var values: [Element] {
        switch self {
        case .leaf:
            return []
        case let .node(e, l, r):
            return l.values + [e] + r.values
        }
    }
}
let tree: BinaryLeef<Int> = .node(6, l: .leaf, r: .leaf)
 print(tree.values)
extension BinaryLeef {
    func map<T>(_ transform: (Element)->T) -> BinaryLeef<T> {
        switch self {
        case .leaf:
            return .leaf
        case let .node(e, l, f):
            return .node(transform(e), l: l.map(transform), r: f.map(transform))
        }
    }
}
 let incremented: BinaryLeef<Int> = tree.map{ $0 + 1 }
 print(incremented)
  • Optional 用泛型参数抽象它包装的类型
  • Result 有两个泛型参数:分别表示成功和失败这两种结果对应的值的类型。
  • Unsafe[Mutable]Pointer 用泛型参数表示指针指向的对象的类型。
  • Key paths 中使用了泛型表示根类型以及路径的值类型。
  • 各种表示范围的类型,使用了泛型表达范围的上下边界

泛型和Any

Any作用相似,但是缺少类型安全性,泛型能带来编译期类型检查以及提高运行时性能等额外的好处

extension Array {
   func reduce<Result>(_ initial: Result,
   _ combine: (Result, Element) -> Result) -> Result
}

extension Array {
   func reduce(_ initial: Any, _ combine: (Any, Any) -> Any) -> Any
}

Any无法得知参数和返回值的关系,不易读

基于泛型的设计

struct User: Codable {}
struct NoDataError: Error {}

extension URLSession {
    func loadUser(callBack: @escaping (Result<User, Error>) -> ()) {
        guard let url = URL(string: "") else { return }
        dataTask(with: url) { data, response, error in
            callBack(Result{
                if let e = error { throw e }
                guard let d = data else { throw NoDataError() }
                return try JSONDecoder().decode(User.self, from: d)
            })
        }.resume()
    }
}
func load<A>(url: URL, parse: @escaping (Data)throws->A, callBack: @escaping (Result<A, Error>) -> ()) {
        dataTask(with: url) { data, response, error in
            callBack(Result{
                if let e = error { throw e }
                guard let d = data else { throw NoDataError() }
                return try parse(d)
            })
        }
    }
     URLSession.shared.loadUser {
            print($0)
     }
        
     guard let url = URL(string: "") else { return }
     URLSession.shared.load(url: url, parse: { data in
             }) {
            print($0)
      }
struct Resource<A> {
    let url: URL
    let parse: (Data) throws -> A
}

let profile = Resource<User>(url: url) { data in
            try JSONDecoder().decode(User.self, from: data)
    }
extension Resource where A: Codable {
    init(json url: URL) {
        self.url = url
        self.parse = { data in
            try JSONDecoder().decode(A.self, from: data)
        }
    }
}

let profile2 = Resource<User>(json: url)

最后定义接受resource的load版本

extension URLSession {
    func load<A>(_ resource: Resource<A>, callBack: @escaping (Result<A, Error>) -> ()) {
        dataTask(with: resource.url) { data, response, error in
            callBack(Result{
                if let e = error { throw e }
                guard let d = data else { throw NoDataError() }
                return try resource.parse(d)
            })
        }
    }
}

let profile2 = Resource<User>(json: url)
URLSession.shared.load(profile2) {
            print($0)
}
上一篇下一篇

猜你喜欢

热点阅读