Swift 的范型 + 扩展,举例

755 阅读1分钟

Swift 的范型 + 扩展,

用于集合类型,很强

范型就是模版,Generic + Extension 很适合搞代码简化

本文通过 6 个例子,体现

例子一

实现这种效果

  • 有数据,一个界面

截屏2021-03-18 下午7.32.53.png

  • 没数据,使用默认界面

截屏2021-03-18 下午7.33.01.png


    var array: [String]?
    
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    
        // 没数据,就返回一个,放默认图
        return array.validCount
    }

因为这种界面比较多,逻辑类似,

具体渲染的 Array.Element 是不同的结构体,所以用范型搞代码简化


extension Optional where Wrapped: Collection{

    var validCount: Int{
        var cnt = 1
        if let source = self{
            cnt = max(source.count, cnt)
        }
        return cnt
    }
}


例子 2

承接上文,

  • 有数据,一个界面,采用自定制 layout 型号一

  • 没数据,使用默认界面,采用自定制 layout 型号 2

var array: [String]?


// 没数据,就 false,
layout.oKey = array.hasData

Optioal, 是 Protocol + Generic,

其 value 是 Wrapped,

Wrapped 遵守 Collection,就可以使用 count 方法


extension Optional where Wrapped: Collection{
    var hasData: Bool{
        var has = false
        if let dat = self, dat.count > 0{
            has = true
        }
        return has
    }
}

例子 3, 安全获取, 保证不越界


extension Array {
    func element(at index: Int) -> Element? {
        guard index >= 0, index < count else {
            return nil
        }

        return self[index]
    }
}

例子 4, 默认获取

// 拆包的方式,挺别致
extension Array  {
    func value<T>(at index: Int, emptyAction: () -> T) -> T where Element == T? {
        if let value = self[index] {
            return value
        }
        return emptyAction()
    }
}

例子 5, 循环调用

extension Sequence where Element == () -> Void {
    func callAll() {
        forEach { closure in
            closure()
        }
    }
}

例子 6, 循环带参数调用

extension Sequence {
    func callAll<T>(with input: T) where Element == (T) -> Void {
        forEach { closure in
            closure(input)
        }
    }
}

PS:

一半例子 ,参考自 The power of extensions in Swift