union在重构代码中的使用技巧

Posted qiyuexin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了union在重构代码中的使用技巧相关的知识,希望对你有一定的参考价值。

http://blog.chinaunix.net/uid-23629988-id-158156.html

 

在产品的开发过程中,无论是代码的重构,还是添加新的功能时,都不可避免的有对现有结构体的修改,比如结构体成员变量名字的修改,类型的变动,等等。如果只是修改名字,使用工具,就可以把所有的改动完成了。但是如果是成员变量的类型发生了变化,就不是不能简单的依靠工具完成了。而且作为人工的工作,每个开发人员的进展速度不一样,如果不能同时完成修改,那么每天的工程的自动build就无法完成。


那么有没有一种技巧,可以避免这种情况呢。
下面举个例子,比如有这样的一个structure
  1. typedef structure {
        char     name[MAX_NAME_LEN];
  2.     unsigned short height;
  3.     // ... ...
  4. } STUDENT_INFO_S;
用于表示学生的个人信息,那么代码中肯定会有很多地方引用name
  1. STUDENT_INFO_S student;
  2. char name[MAX_NAME_LEN]
  3. // ......
  4. strncpy(name, student.name, sizeof(name)-1);
但是现在有了新的需求。不能直接把学生的姓名直接存入一个字符数组了,而是需要一个结构体
  1. typedef {
  2.    char name[MAX_NAME_LEN];
  3.    char first_name[MAX_NAME_LEN];
  4.    char last_name[MAX_NAME_LEN];
  5. } NAME_INFO_S;
如果我们直接使用这个结构体作为新的name类型,来取代原有的字符数组,
  1. typedef structure {
  2.     NAME_INFO_S name;
  3.     unsigned short height;
  4.     // ... ...
  5. } STUDENT_INFO_S;
那么毫无疑问,在不修改代码的情况下,会有很多地方无法通过编译。如果这样的地方很多,我们为了不妨碍每天的自动build,可能会快速的修改以前的代码——这无疑有着一定的引入bug的风险。
 
那么遇到这种情况时,我们可以使用union来避免这个问题,既在新的代码中可以使用新的结构体,同时又不会影响build和以前代码的逻辑。
  1. typedef structure {
  2.     union {
  3.         char name[MAX_NAME_LEN];
  4.         NAME_INFO_S name_info;
  5.     };
  6.     unsigned short height;
  7.     // ... ...
  8. } STUDENT_INFO_S;
这里应用了gcc的一个扩展特性,当不对union或者struct命名时,外层可以直接引用union或者struct中的成员变量。比如STUDENT_INFO_S student, 我们可以直接使用student.name_info或者student.name。
 
通过这样一个小技巧,我们可以在新的代码中,使用新的成员变量,同时不会影响到以前代码的编译。如果新的类型中,包含了以前老的类型且位于第一个时,甚至不会影响到以前老代码的逻辑。这样可以允许开发人员仔细的,慢慢修改以前的代码。

 

以上是关于union在重构代码中的使用技巧的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE 11G 中的 WITH 子句使用 UNION ALL

如何使用Unions更有效地进行LINQ查询

SQL中的union

使用 UNION ALL 合并 Hive 中的许多表?

Eclipse 中的重构功能

Mysql联合查询UNION和UNION ALL的使用介绍