源码阅读笔记之--<Stencil源码阅读>

源码阅读笔记之--<Stencil源码阅读>,第1张

GitHub链接:https://github.com/stencilproject/Stencil 一、defer 读到这段有个小疑惑,defer是干啥的
/// Push a new level onto the context for the duration of the execution of the given closure
  public func push(dictionary: [String: Any] = [:], closure: (() throws -> Result)) rethrows -> Result {
    push(dictionary)
    defer { _ = pop() }
    return try closure()
  }
笔记如下<详情参看这篇文章>

defer翻译成中文,是"推迟"的意思。
1.在代码块结束之前,或调用return、break之前,会调用这个defer里面的内容
2.简单来说,就是一个代码块,即将结束时候的“遗言”
3.如果有多个defer,那么是从下到上,反着执行

二、异常抛出的方式 源码如下
public class TemplateDoesNotExist: Error, CustomStringConvertible {
  let templateNames: [String]
  let loader: Loader?

  public init(templateNames: [String], loader: Loader? = nil) {
    self.templateNames = templateNames
    self.loader = loader
  }

  public var description: String {
    let templates = templateNames.joined(separator: ", ")
      
    if let loader = loader {
      return "Template named `\(templates)` does not exist in loader \(loader)"
    }

    return "Template named `\(templates)` does not exist. No loaders found"
  }
}
笔记如下:
class StencilClass {
    func loadName(name: String) throws -> String {
        let myName = name
        if myName == "张三" {
            return "Success"
        } else {
            throw StencilError(stencilError: name)
        }
    }
}

class StencilError: Error,CustomStringConvertible {
    let myError: String
    
    public init(stencilError: String) {
        self.myError = stencilError
    }
    
    public var description: String { // 遵守这个协议CustomStringConvertible,就要实现这个属性
        return "这次报错 \(myError)"
    }
}
调用
try StencilClass().loadName(name: "张三1")
报错内容

Swift/ErrorType.swift:200: Fatal error: Error raised at top level: 这次报错 张三1
[5613:7424652] Swift/ErrorType.swift:200: Fatal error: Error raised at top level: 这次报错 张三1
(lldb)

ps:这篇文章也可以参考下

三、Equatable
class StreetAddress: Equatable {
    static func == (lhs: StreetAddress, rhs: StreetAddress) -> Bool { // 只要遵守这个Equatable协议,就要实现这个方法
        return
            lhs.street == rhs.street &&
            lhs.number == rhs.number
    }
    
    let number: String
    let street: String
    
    init(_ number: String, _ street: String) {
        self.number = number
        self.street = street
    }
    
}
let a = StreetAddress("0", "1")
let b = StreetAddress("1", "1")
let res = a == b // 打印false
四、高阶函数

推荐博客

func test() {
        // map
        // 1. 读每个元素计算
        var values1 = [1,2,3,4,5]
        values1 = values1.map{$0 + 10}
        print("values1 == ",values1) // [11, 12, 13, 14, 15]
        
        // 2. 对元素字符个数计算
        let strs = ["JiB", "MotuoKe", "NiuBi", "DaHa", "DanDan"]
        let cnts = strs.map({$0.count})
        print("cnts == ", cnts) // cnts ==  [3, 7, 5, 4, 6]
        
        // 3. 变小写
        let lowerStrs = strs.map({$0.lowercased()})
        print("lowerStrs == ", lowerStrs) // lowerStrs ==  ["jib", "motuoke", "niubi", "daha", "dandan"]
        
        
        // flatMap : 降维(3维降2维,2维降1维),不存在nil, 自动解包
        // compactMap : 可选值自动解包
        let values = [[1,2,3],[4,5,6],[7,8,9]]
        let res = values.compactMap { e in
            return e
        }
        print(res) // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        
        let res1 = values.compactMap({$0})
        print(res1) // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        
        let res2 = values.flatMap({$0}) // 二维降一维
        print(res2) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
        
        let array = ["1", "two", "3", "4", "five", "6"]
        let maps: [Int?] = array.map({Int($0)}) // 可选的
        print("maps == ",maps)  // maps ==  [Optional(1), nil, Optional(3), Optional(4), nil, Optional(6)]
        
        let compactMaps = array.compactMap({Int($0)}) // 自动解包
        print("compactMaps == ",compactMaps) // compactMaps ==  [1, 3, 4, 6]
        
        let values3 = [[[1,2,3],[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]]]
        let res3 = values3.flatMap({$0}) // 三维降二维
        print("res3 == ", res3) // res3 ==  [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
        
        // filter: 条件过滤函数
        var values2 = [6, 7, 8, 9]
        values2 = values2.filter{$0 > 7}
        print("values2 == ", values2) // [8, 9]
        
        // reduce: 叠加递增器函数
        // 1. 拼接元素
        let arr = ["love","you", "so", "much"]
        let resArr = arr.reduce("I") { (partialResult, curStr) -> String in
            return partialResult + " " + curStr
        }
        print("resArr == ", resArr) // resArr ==  I love you so much
        // 2. 计算元素字符个数
        let coutArr = arr.reduce(0) { (partialResult, curStr) -> Int in
            return partialResult + curStr.count
        }
        print("count == ",coutArr) // count ==  13
        
        // 3. 计算字符串中相同字符,通过字典
        let letters = "avbracdgbbcc"
        let letterDict = letters.reduce(into: [:]) { partialResult, char in
            partialResult[char, default: 0] += 1
        }
        print("letterDict == ", letterDict) // letterDict ==  ["v": 1, "c": 3, "d": 1, "b": 3, "a": 2, "r": 1, "g": 1]
        
        // 4. 计算二维数组的总和,map配合reduce使用
        let arrays1 = [[5,2,7],[4,8],[9,1,3]]
        let sums = arrays1.map({$0.reduce(0, +)})
        // 等价于
        let sums1 = arrays1.map({$0.reduce(0) { (partialResult, ele) -> Int in
            return partialResult + ele
        }})
        
        print("sums == ", sums, "\n" , "sums1 == ", sums1) // sums ==  [14, 12, 13]
        // sums1 ==  [14, 12, 13]
    }
五、三引号和反斜杠的细节

看到下面的代码,有点眼生:

let highlight = """
        \(String(Array(repeating: " ", count: location.lineOffset)))\
        ^\(String(Array(repeating: "~", count: max(token.contents.count - 1, 0))))
        """

因为平时用到比较少,就记录一下。

let highlight = """
  张三
 \(String(Array(repeating: "a", count: 4)))
 ^
 ---
 是\
 \(String(Array(repeating: "~", count: 4)))\
 帅哥
 """

打印内容:

 张三
aaaa
^
---
是~~~~帅哥
三引号,里面内容会自动换行,不用额外加\n在每一行最后面加一个\ 是可以与下面一行内容连接在一行
六、final关键字使用

详情参考这篇文章,写的挺好的
我在大概总结几句,一般场景用于工具类或方法里面

权限控制,就是说,写在class前面,不想这个class被别人继承。写在func前面,当这个func的类被继承后,这个func是不能被重写的。 七、class func 和 static func
都是表示静态方法static func 不能被继承,等价于 class final func (CFF,联想到CF游戏, 这样记忆,保证顺序)
八、zip函数,不是压缩文件,而是swift的接口

这篇文章不错

let a = [1, 2, 3, 4, 5]
let b = ["a", "b", "c", "d"]

let c = zip(a, b).map {$0}
print("c ->", c) // c -> [(1, "a"), (2, "b"), (3, "c"), (4, "d")]
let d = zip(1..., b).map {$0}
print("d ->", d) // d -> [(1, "a"), (2, "b"), (3, "c"), (4, "d")]


let dict = Dictionary(uniqueKeysWithValues: zip(a, b))
print("dict ->", dict) // dict -> [3: "c", 4: "d", 2: "b", 1: "a"]
let array = ["Apple", "Pear", "Pear", "Orange"]
let dict1 = Dictionary(zip(array, repeatElement(1, count: array.count)), uniquingKeysWith: +)
print("dict1 ->", dict1) // dict1 -> ["Apple": 1, "Orange": 1, "Pear": 2]


let a1 = ["a", "b", "c", "d"]
let b1 = ["A", "B", "C", "D"]
let c1 = [a1,b1].flatMap({$0}) // 分批合并
print("c1 ->", c1) // c1 -> ["a", "b", "c", "d", "A", "B", "C", "D"]
let c2 = zip(a1, b1).flatMap({ [$0, $1]}) // 交替合并
print("c2 ->", c2) // c2 -> ["a", "A", "b", "B", "c", "C", "d", "D"]
zip的骚气用法
override func viewDidLoad() {
        super.viewDidLoad()
        
        let titles = ["按钮1", "按钮2", "按钮3"]
        let colors = [UIColor.red, UIColor.blue, UIColor.orange]
         
        let buttons = zip(0..., titles).map { (i, title) -> UIButton in
            let button = UIButton(type: .system)
            button.frame = CGRect(x: i * 100, y: 200, width: 80, height: 80)
            button.setTitle(title, for:.normal)
            button.tag = i
            self.view.addSubview(button)
            return button
        }
        
//        zip(buttons, colors).forEach { (btn, color) in
//            btn.backgroundColor = color
//        } // 简化如下写法:
        
        zip(buttons, colors).forEach({
            $0.0.backgroundColor = $0.1
        })
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/990455.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存