led外贸网站制作,网站建设的主题,东莞网站优化方案,广州网站开发公司哪家好可能经常有如下这种需求: 需要一张表,来记录学员课程的通过与否. 课程数量不确定,往往很多,且会有变动,随时可能新增一门课. 这种情况下,在设计表结构时,一门课对应一个字段,就有些不合适, 因为不知道课程的具体数量,也无法应对后期课程的增加. 考虑只用一个状态标志位,利用位运… 可能经常有如下这种需求: 需要一张表,来记录学员课程的通过与否. 课程数量不确定,往往很多,且会有变动,随时可能新增一门课. 这种情况下,在设计表结构时,一门课对应一个字段,就有些不合适, 因为不知道课程的具体数量,也无法应对后期课程的增加. 考虑只用一个状态标志位,利用位运算,来标识多门课的通过或否. 这与Linux的文件权限思路一致 Linux文件和目录的权限 设计及实现 左移: 右移: |或运算只要当一方为 true 时结果就是 true否则为 false。 (有1就为1,全0才为0) 与运算只有当两方都为 true 时结果才是 true否则为 false。(全1才为1,有0就为0) 对于正数和负数左移一位就相当于乘以2的1次方左移n位就相当于乘以2的n次方 如xxxxxx2即左移2位,右边空出的位用0填补高位左移溢出则舍弃该高位 步骤一: 如语文成绩率先出来,我们约定,以这个字段(记为attr)的第一位,来代表该学生语文有没有通过测评(0否1是) attr为当前该属性字段的值(从数据库里取出来的值). index为约定的第几位来标识当前业务,index从0开始计数 package mainimport fmtfunc main() { // 记录阶段 //如果语文成绩测评通过,调一个写接口,初始attr值为0,约定的表示位置为第1位,又因为从0开始计数,故而index0 setRs : set(0, 0) //将attr字段的最新值,记录进数据库的attr字段 // 查询阶段 //当需要获知该学生的语文是否通过时. 查数据库,获取上面记录进的值(此时setRs即attr1); 进而get方法,可知道是否通过(如果rs结果为1,则通过) rs : get(setRs, 0) _ rs}func set(attr, index int) int { tmp : 1 index // 1左移0位,即原地没动,还是1 fmt.Printf(1 index %d 值为%d:\n, index, tmp) // 1 | 0,或运算,有1就为1,故而setRs1 setRs : tmp | attr fmt.Println(setRs) return setRs}func get(attr, index int) int { tmp : attr index // 1右移0位,即原地不动,还是1 fmt.Printf(attr %d index %d 值为 %d:\n, attr, index, tmp) // 0001 0001,与运算,全1才为1,故而为0001,即为十进制数1 getRs : tmp 1 fmt.Println(getRs) return getRs} 输出为: 1 index 0 值为1:1attr 1 index 0 值为 1:1 假设孙山语文及格, 张继语文落榜(则不调用写接口,只有通过才调),则二人当前attr的值为1和0. 这样就完成了语文科目的处理 步骤二: 几天后数学测评结果也出来了,继续用attr,约定以这个字段的第二位,来代表该学生数学有没有通过测评(0否1是) 同样用之前的代码, 记录阶段: package mainimport fmtfunc main() { // 记录阶段 //如果数学成绩测评通过,调写接口,约定的表示位置为第1位,又因为从0开始计数,故而index1 // 对于孙山,从数据库取出其attr值,为1; 张继的attr值为0 // 加入二人都通过了数学测评,都需调用如下写接口 setRsSun : set(1, 1) //将attr字段的最新值,记录进数据库的attr字段 fmt.Println(-----------) setRsZhang : set(0, 1)}func set(attr, index int) int { tmp : 1 index // 1左移1位,即由0001变为0010,即为十进制数2 fmt.Printf(1 index %d 值为%d:\n, index, tmp) // 对于语文通过带孙山,0010 | 0001,或运算,有1就为1,故而setRs0011,即十进制数3 // 对于语文未通过带张继,0010 | 0000,或运算,有1就为1,全0才为0, 故而setRs0010,即十进制数2 setRs : tmp | attr fmt.Println(setRs) return setRs} 1 index 1 值为2:3-----------1 index 1 值为2:2 查询阶段: package mainimport fmtfunc main() { // 查询阶段 //当需要获知该学生的语文/数学是否通过时. 查数据库,获取其attr的值; 进而get方法,index字段为该科目约定的位置(语文为1,其index为0; 数学为2,其index为1),即可知道是否通过(如果rs结果为1,则通过) sunMath : get(setRsSun, 1) //setRsSun3 fmt.Println(-----------) zhangChinese : get(setRsZhang, 0)//setRsZhang2 fmt.Println(sunMath is:,sunMath) fmt.Println(zhangChinese is:,zhangChinese)}func get(attr, index int) int { tmp : attr index fmt.Printf(attr %d index %d 值为 %d:\n, attr, index, tmp) getRs : tmp 1 fmt.Println(getRs) return getRs} // 对于孙山,十进制数3即二进制0011,右移1位,即0001,即十进制数1attr 3 index 1 值为 1:// 0001 0001,与运算,全1才为1,故而为1. 即孙山通过了数学1-----------// 对于张继,十进制数2即二进制0010,右移0位,即原地不动,还是0010,十进制数2attr 2 index 0 值为 2:// 0010 0001,全1才为1,否则为0. 即张继没有通过语文0sunMath is: 1zhangChinese is: 0 步骤三: 过了几天,英语结果也出来了.假如孙山没通过,张继通过,爽哥三门都通过,则有 写入和读取过程同上 步骤四: 假如现在第60个科目信息技术的测评出炉, 爽哥前面59门课程全部通过,则attr字段的值为 , 即 2的n次方对照表 第60门课信息技术也高分通过, 则对于最新的attr值,即 1 index | attr, 即1 59 | 576460752303423487 1152921504606846975,将这个值计入数据库. 如需获取爽哥有无通过第60门课程,1152921504606846975 59 1 1,即通过 如果将数据库这个attr字段设置为有符号的bigint类型,则最多可标识 60几个不同业务的状态 更通用的代码: func main(){ index : uint8(约定的位置 - 1) attr : 来自数据库}func SetAttrBit(attr int, index uint8) int { return 1 index | attr}func GetAttrBit(attr int, index uint8) int { return attr index 1} 参考: 用位运算来标识状态 番外 光学电报 本文由 mdnice 多平台发布