swift的位运算及resultBuilder
前提:swift不同数值类型无法进行运算的操作。比如Int16的数值类型不能和Int8的数值类型做加减乘除等操作
所以在进行位运算的时候也不能用Int16的数值类型和Int8的数值类型进行与或非等操作。接下去的均以相同的类型进行运算
一、位运算
1、无符号的位运算均与C语言的操作一样,这里就不再赘述
2、有符号的位运算
1、数值的二进制设置:let initBit: Int8 = 0b00001111; 这里将二进制数值设置给initBit是正常的操作。但是我们知道在C语言中如果最高位为1则是负数,那么我们能否这样初始化呢?let initBit: Int8 = 0b10001111; 答案是不行的,在这里会提示已经溢出了。所以如果要赋值负数则应该为let initBit: Int8 = -0b00001111;
2、虽然上述的赋值运算不能在最高位设置为1来代表负数,但是当赋值完成之后,接下去的与或非移位等运算却又与无符号的位运算一致。如下所示
let bit1: Int8 = -0b00001111 // 计算机底层均是以补码的形式存在数值是:0b11110001 负数是符号位除外其他位按位取反再加1 let bit2: Int8 = 0b01111000 print(bit2 & bit1) // 112 0b01110000 print(bit2 << 1) // -16 0b11110000
3、虽然swift的加减乘除等操作正常情况下是不允许溢出,但是移位运算产生的溢出则不会抛出异常,比如: bit2 << 10; 理论上这样子的操作要溢出,但是却没问题。
二、resultBuilder
当我们要构造数组或者要在数组里面增加额外的if或者for等操作来生成一个或者多个对象是,如果用普通的方式整体的代码会晦涩难懂;而如果用resultBuilder的话,整个代码的结构则会清晰很多
比如例子:

protocol Drawable { func draw() -> String } struct Line: Drawable { var elements: [Drawable] func draw() -> String { return elements.map { $0.draw() }.joined(separator: "") } } struct Text: Drawable { var content: String init(_ content: String) { self.content = content } func draw() -> String { return content } } struct Space: Drawable { func draw() -> String { return " " } } struct Stars: Drawable { var length: Int func draw() -> String { return String(repeating: "*", count: length) } } struct AllCaps: Drawable { var content: Drawable func draw() -> String { return content.draw().uppercased() } }
let name: String? = "Ravi Patel" let manualDrawing = Line(elements: [ Stars(length: 3), Text("Hello"), Space(), AllCaps(content: Text((name ?? "World") + "!")), Stars(length: 2), ]) print(manualDrawing.draw())
整体代码虽然看的懂,但是不够清晰,特别是AllCaps的Text((name ?? "World")操作判断 如果name存在则使用name,否则使用"World"
如果能够使用如下的方法进行调用的话,则整体的代码虽然多了一些,但是更清晰并且更符合swift的特性
func draw(@DrawingBuilder content: () -> Drawable) -> Drawable { return content() } func caps(@DrawingBuilder content: () -> Drawable) -> Drawable { return AllCaps(content: content()) }
func makeGreeting(for name: String? = nil) -> Drawable { let greeting = draw { Stars(length: 3) Text("Hello") Space() caps { if let name = name { Text(name + "!") } else { Text("World!") } } Stars(length: 2) } return greeting } let genericGreeting = makeGreeting() print(genericGreeting.draw())
resultBuilder为上述的操作创造了可能,上面用到的特性有
1、draw后面的block 2、caps后面的block 3、caps里面的if-else 4、caps里面if 的block和else的block
只要需要应用到的这些特性均需要在resultBuilder中体现出来,如下所示
@resultBuilder struct DrawingBuilder { static func buildBlock(_ components: Drawable...) -> Drawable { return Line(elements: components) } static func buildEither(first: Drawable) -> Drawable { return first } static func buildEither(second: Drawable) -> Drawable { return second } }
在caps中,假设name有值;则先调用if(通过调用first返回), 接着调用if后面的block然后再调用caps后面的block
通过caps的流程可以看出不管调用哪个,最后均需要通过block返回。所以在resultBuilder 中,buildBlock一定要构造
具体的resultBuilder使用说明可以看这个链接:https://www.cnswift.org/attributes#resultBuilder
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!