表达太复杂的错误。如果我做错了,请纠正我

时间:2017-12-05 12:13:53

标签: swift

let b0 = UInt32(block[block.startIndex + 0 + (0 << 2)]) << 0 | UInt32(block[block.startIndex + 1 + (0 << 2)]) << 8 | UInt32(block[block.startIndex + 2 + (0 << 2)]) << 16
        b0 = b0 | UInt32(block[block.startIndex + 3 + (0 << 2)]) << 24
    let  b1 = UInt32(block[block.startIndex + 0 + (1 << 2)]) << 0 | UInt32(block[block.startIndex + 1 + (1 << 2)]) << 8 | UInt32(block[block.startIndex + 2 + (1 << 2)]) << 16
        b1 = b1 | UInt32(block[block.startIndex + 3 + (1 << 2)]) << 24
    let b2 = UInt32(block[block.startIndex + 0 + (2 << 2)]) << 0 | UInt32(block[block.startIndex + 1 + (2 << 2)]) << 8 | UInt32(block[block.startIndex + 2 + (2 << 2)]) << 16
        b2 = b2 | UInt32(block[block.startIndex + 3 + (2 << 2)]) << 24
    let b3 = UInt32(block[block.startIndex + 0 + (3 << 2)]) << 0 | UInt32(block[block.startIndex + 1 + (3 << 2)]) << 8 | UInt32(block[block.startIndex + 2 + (3 << 2)]) << 16
        b3 = b3 | UInt32(block[block.startIndex + 3 + (3 << 2)]) << 24

1 个答案:

答案 0 :(得分:2)

如果您只是正确格式化此代码,您会发现这是一个非常明确的模式:

let start = block.startIndex

let b0 = UInt32(block[start + 0 + (0 << 2)]) << 0
       | UInt32(block[start + 1 + (0 << 2)]) << 8
       | UInt32(block[start + 2 + (0 << 2)]) << 16
       | UInt32(block[start + 3 + (0 << 2)]) << 24

let  b1 = UInt32(block[start + 0 + (1 << 2)]) << 0
        | UInt32(block[start + 1 + (1 << 2)]) << 8
        | UInt32(block[start + 2 + (1 << 2)]) << 16
        | UInt32(block[start + 3 + (1 << 2)]) << 24

let b2 = UInt32(block[start + 0 + (2 << 2)]) << 0
       | UInt32(block[start + 1 + (2 << 2)]) << 8
       | UInt32(block[start + 2 + (2 << 2)]) << 16
       | UInt32(block[start + 3 + (2 << 2)]) << 24

let b3 = UInt32(block[start + 0 + (3 << 2)]) << 0
       | UInt32(block[start + 1 + (3 << 2)]) << 8
       | UInt32(block[start + 2 + (3 << 2)]) << 16
       | UInt32(block[start + 3 + (3 << 2)]) << 24

每个b常量只是以类似方式转换的数字0...3,所有按位“或”在一起。听起来像是map / reduce

的工作
let start = block.startIndex
let b0 = (0...3).lazy.map{ UInt32(block[start + $0 + (0 << $0)]) << $0 * 8 }.reduce(0, |)
let b1 = (0...3).lazy.map{ UInt32(block[start + $0 + (1 << $0)]) << $0 * 8 }.reduce(0, |)
let b2 = (0...3).lazy.map{ UInt32(block[start + $0 + (2 << $0)]) << $0 * 8 }.reduce(0, |)
let b3 = (0...3).lazy.map{ UInt32(block[start + $0 + (3 << $0)]) << $0 * 8 }.reduce(0, |)

如果您创建一个包含4个元素的b数组,而不是4个单独的b#变量,则可以进一步简化:

let start = block.startIndex
let b = (0...3).map{ x -> UInt32 in
    fatalError("I don't know what the number x represents, so I just named it x. Give it a better name.")
    return (0...3).lazy
                  .map{ UInt32(block[start + $0 + (x << $0)]) << $0*8 }
                  .reduce(0, |)
}