前提: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的话,整个代码的结构则会清晰很多

比如例子:

swift 返回Stream数据 swift result builder_swift 返回Stream数据

swift 返回Stream数据 swift result builder_Text_02

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() }
}

View Code

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