请给代码多留一些空间

oschina
 oschina
发布于 2014年06月09日
收藏 44

最近在几个不同的团队中发现他们的编码规范中对空格的用法大不相同。这激起了我的好奇心,因为我一直觉得,对于代码格式中的空格的使用,应该有一个大家都公认的最好的习惯。但是在现实开发中,似乎没有出现这样的统一。

现状

首先,我们看看在大多数Java IDE中Java代码的风格习惯。

下面是一个例子:

public class Example {

public static void main(String[] args) {
    int answer = 2 + 4 * 6;
    for (int i = 0; i < 5; i++) {
        doSomething();
    }
    System.out.println("The answer is " + answer);
}

    private static void doSomething() {
        // something
    }
}

请注意,这是Java编程者中和其它类似C语言的语言中最常见的一种风格

在括号内部两边没有留空格。只有当括号前面有关键字forwhile等时,空格才会出现在它们之间,但在方法名和其之后的括号间没有空格。然而,在左大括号前总会有空格(这个左大括号一般会出现在一行的最后)。数学操作符总有空格包围。而分号前不会有空格。

如果你经常阅读代码,也许认为这是很自然的安排,但如果你不是一个程序员,可能会认为这些规则太随意,有很多不统一、特例、有待讨论的地方。

请给你的代码留下多一些空间

在我当前的开发项目中,公司里有两个主要的开发团队,一个是Load Test Products(LTP)团队,另一个是Functional Test Products(FTP)团队。两个团队里遵守了一些编码风格习惯,其中对空格的使用都是特别慷慨,就像下面这个代码片段的例子:

public class Example
{

    public static void main( String[] args )
    {
        int answer = 2 + 4 * 6;
        for( int i = 0; i < 5; i++ )
        {
            doSomething();
        }
        System.out.println( "The answer is " + answer );
    }

    private static void doSomething()
    {
        // something
    }

}

这种风格看起来代码的密度更小,而且更有统一性(例如,在左括号前都没有空格,在所有的括号、花括号、中括号的左右内边都有空格)!我并不是说这样比之前的风格更好或更差….只是这样更容易区别单词。代价就是一个屏幕里只能显示更少的代码。

虽然每种编码风格都有各自的优势和缺点,但让我吃惊的是,FTP开发团队最终决定转向使用之前提到的最常见的那种编码风格。他们认为这种转变是值得 的,他们甚至还进行过讨论,所以,我相信他们认为这种转变是重要的。他们判断的依据并不是这种比那种好…我认为这主要着眼于什么人习惯这种风格,因为我们 的大部分产品都是开源的,这是重要原因,更容易让社群内的程序员捐赠代码。

在我的团队里,LTP团队,我们仍然坚持我们的风格,不打算做任何改变。至少对于我来说,这是一种基于技术考虑的决定:如果另一种编码风格没有体现出任何的优势(我们的这个项目对开源捐赠的需求很少),为什么要转向另一种风格?

规则需要统一

我一直在给开源项目捐赠代码,比如Ceylon编程语言,让我非常吃惊的是,他们完全没有遵守任何的编码风格。你可以用任何你喜欢的风格来写代码。

也许某些被一些公司里大量的编码规范惊吓住的程序员会喜欢这样,但我相信,如果没一套编码规范,你的项目的代码很可能在格式上出现混乱。每个代码捐赠者都会在提交的代码里带入他特有的代码风格,这不奇怪,结果就是所有的代码各式各样,你从下面几行代码里就能看到多种不同的风格:

while (exists cell = iter) {
        if (exists elem = cell.element,
        elem==element) {
            last = cell;
        }
        iter = cell.rest;
    }
}

if (exists cell=last){
    cell.element=replacement;
    return true;
}
assert (0<=index<length);

我主要想提出的问题是:编码风格究竟是不是一种重要的开发制度?它对程序员开发软件的效率有多大影响?

我相信这个问题牵连到另外一个相似的问题:代码的格式影响代码的可读性吗?

代码格式影响代码的可读性

我认为,这个问题非常容易回答!当然会影响。用眼睛逐行扫描一下下面两段代码(从Ceylon项目中选出的),你会很容易感觉到哪个更易读。 – CeylonCreate)?

function validModuleNameChar(Character c)=>c.letter||c.digit||c in ['_','.' ];
if (!trimmedName.empty,
    validModuleNameFirstChar(trimmedName.first else 'X'),
    trimmedName.every(validModuleNameChar),
    !(trimmedName.split('.'.equals,true,false)).containsAny(ceylonKeywords.chain {""})) {
    return trimmedName;
}
function validModuleNameChar( Character c ) => c.letter || c.digit || c in ['_', '.' ];
if ( ! trimmedName.empty,
    validModuleNameFirstChar ( trimmedName.first else 'X' ),
    trimmedName.every ( validModuleNameChar ),
    ! ( trimmedName.split ( '.'.equals, true, false ) ).containsAny ( ceylonKeywords.chain { "" } ) )
{
    return trimmedName;
}

它们的区别也许很小,但如果你整天花大量的时间读大量的代码,这区别就大了。

从普通文字写作中学到的经验

说起代码的可读性,我们也许应该看看人们更普通的阅读文字的能力,这种能力已经发展了几千年,所以,应该会总结出来更好的方案!?

在“普通”的英文中,你可以看出约定俗成的对于空格的用法,而你却看不到作家们讨论他们是否应该在括号周边使用空格的问题!
那么,如果代码像“普通”英文那样编写,会是什么样子?

回到我们上面简单的例子:

function validModuleNameChar( Character c ) => c.letter || c.digit || c in ['_', '.' ];
if ( ! trimmedName.empty,
    validModuleNameFirstChar ( trimmedName.first else 'X' ),
    trimmedName.every ( validModuleNameChar ),
    ! ( trimmedName.split ( '.'.equals, true, false ) ).containsAny ( ceylonKeywords.chain { "" } ) )
{
    return trimmedName;
}

代码里大部分的东西都本普通英文句子一样。你使用括号将某些字词“分组”。你在单词和符号之间使用空格——这里我们发现了一个跟普通编码习惯不一样的地方:我们在调用方法时,方法名和之后的括号间没有空格,对象点操作符后面不留空白。

我可以理解为什么在这些地方没有空格,因为代码里这些括弧或点号表示了一种“拥有”关系,或关联关系。但真的有必要挤压这一点空间来表示这种关系吗?当我们看上面的这个例子代码时不是感觉很清晰吗?

另外一个在普通英文里不存在的东西是嵌套表达…所以,我们有普通英文写作里不会出现的情况。但这不是大问题,只需要在记住一个通用规则:在符号两边加空格。

你是不是感觉上面的代码有些奇怪?我不得不承认,看起来稍微有些不舒服,当我相信这只是我还不习惯。

虽然还不习惯,但我确定这些代码读起来更容易理解。

我可以明确的说,如果所有的代码都遵守这样的习惯,那我们程序员阅读代码的过程将会轻松的多。

结束语

我希望没有程序员会认为遵守一个预先定义的编码规范会让编程变得困难!

首先,所有的IDE都能配置成自动对代码进行格式规范调整,你写代码时可以写的很乱,但最后别忘了使用IDE里的快捷键整理一下代码,然后再提交代码。同样,我估计没有哪个作家会认为我们的写文字的格式太严,限制了他的创作。

幸运的是,我发现当前所有的编码风格、规范里对空格的使用习惯都没有大问题。但多使用一些空格肯定会让代码更清晰易读。

你觉得呢?

[英文原文:Give your code some space! ]

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 OSCHINA 社区 [http://www.oschina.net]
本文标题:请给代码多留一些空间
加载中

最新评论(46

wuyiw
wuyiw

引用来自“pollex”的评论

function x()
{
}

function x() {
}

明显第一种是严谨的,结构性的,最规范的风格。第二种是不注重代码质量的程序员喜欢用的,随意散乱,还不对称。
jQuery 使用的就是第二种.
Undeadway
Undeadway

引用来自“pollex”的评论

function x()
{
}

function x() {
}

明显第一种是严谨的,结构性的,最规范的风格。第二种是不注重代码质量的程序员喜欢用的,随意散乱,还不对称。

引用来自“Undeadway”的评论

如果是 JS ,编译器很可能将第一种解释为 function();
{
};

引用来自“pollex”的评论

还没有遇到过这么差的编译器。

引用来自“Undeadway”的评论

这不是编译器的问题,而是JS标准就支持这种写法——允许不用分号结尾。

引用来自“pollex”的评论

可是我写JS一直就是这么写的啊,没有任何问题
函数定义应该不会,但其他情况就可能了,比如return(《JS 语言精粹》中提到过这个例子),所以推荐将括号写在行末。既然如此,为了保持整体风格的一致,都写行末不更好么。
扶风
扶风

引用来自“pollex”的评论

function x()
{
}

function x() {
}

明显第一种是严谨的,结构性的,最规范的风格。第二种是不注重代码质量的程序员喜欢用的,随意散乱,还不对称。
還是習慣第一種
pollex
pollex

引用来自“pollex”的评论

function x()
{
}

function x() {
}

明显第一种是严谨的,结构性的,最规范的风格。第二种是不注重代码质量的程序员喜欢用的,随意散乱,还不对称。

引用来自“Undeadway”的评论

如果是 JS ,编译器很可能将第一种解释为 function();
{
};

引用来自“pollex”的评论

还没有遇到过这么差的编译器。

引用来自“Undeadway”的评论

这不是编译器的问题,而是JS标准就支持这种写法——允许不用分号结尾。
可是我写JS一直就是这么写的啊,没有任何问题
Undeadway
Undeadway

引用来自“pollex”的评论

function x()
{
}

function x() {
}

明显第一种是严谨的,结构性的,最规范的风格。第二种是不注重代码质量的程序员喜欢用的,随意散乱,还不对称。

引用来自“Undeadway”的评论

如果是 JS ,编译器很可能将第一种解释为 function();
{
};

引用来自“pollex”的评论

还没有遇到过这么差的编译器。
这不是编译器的问题,而是JS标准就支持这种写法——允许不用分号结尾。
pollex
pollex

引用来自“pollex”的评论

function x()
{
}

function x() {
}

明显第一种是严谨的,结构性的,最规范的风格。第二种是不注重代码质量的程序员喜欢用的,随意散乱,还不对称。

引用来自“Undeadway”的评论

如果是 JS ,编译器很可能将第一种解释为 function();
{
};
还没有遇到过这么差的编译器。
Undeadway
Undeadway

引用来自“pollex”的评论

function x()
{
}

function x() {
}

明显第一种是严谨的,结构性的,最规范的风格。第二种是不注重代码质量的程序员喜欢用的,随意散乱,还不对称。
如果是 JS ,编译器很可能将第一种解释为 function();
{
};
吴峻申
吴峻申
其实是个人喜好问题,我现在看到花括号另起一行的就非常不舒服,总觉得这样的代码可读性太差~
开源中国匿名会员
开源中国匿名会员

引用来自“inuxor”的评论

嗯,能空格就空格,该空行就空行。
但是,花括号另起一行属于异端邪说,空一格放行尾才是正教。

引用来自“Toshiojkx”的评论

举双手赞成啊,可以我们公司编码规范有一条"花括号必须另起一行且独占一行",唉,写起都不舒服

引用来自“ViperWhip”的评论

花括号另起一行看起来比较对称

引用来自“wgcn”的评论

但是显示器纵向区域很有限啊~~尤其是在16:9的情况下,绝对是反程序员啊。。

引用来自“Krize.X”的评论

花括号另起一行 自己看着就不舒服···当然不是最后那个花括号

引用来自“摔死的鸟”的评论

习惯了编辑器的 自动格式化,所以看不惯花括号另起一行。哈

引用来自“不算帅”的评论

calss定义/method定义 独占一行,其他情况放行尾

引用来自“开源中国匿名会员”的评论

花括号另起一行会舒服很多。不管现在显示屏是16:9还是4:3,我相信你的视力范围是有限的,大多数人还是遵循80/96/100字符回行的。也是大多数人都遵循函数短细快的。就像swift那样,用 -> 定义返回值之后,再在返回值后面加个括号,要找匹配的时候往上扫一眼,根本看不到,相当难受。花括号另起一行,看起来会更舒服。

就像 vb.net 一样(我不喜欢vb.net,觉得它真的好丑,但是工整就是了,举个栗子)。

Public Function HelloKitty(width As string, height As string) As string
Return String.Format("Hello Kitty")
End Function

这不是很好么。个人觉得,花括号放后面的,主要原因是压缩函数行高,这个问题主要出现在 Javascript上。不停的回调回调,然后在最后你会看到一大堆括号。这是相当蛋疼的。Koa 那种 ES6 处理回调方式,把函数压平之后,另起一行还是很好看的。

自动格式化不是理由,dotNet系的都是另起一行,或者说项目的格式配置都是另起一行。

引用来自“孤月蓝风”的评论

初学时,一直使用的每个花括号单独一行,时间久了,变成了开始花括号放行结尾,结束花括号单独一行,确实是显示器可以容纳的代码太少,所以一屏竟是花括号,看不到什么上下文代码

引用来自“wuyiw”的评论

Javascript在最后看到一大堆括号+10086
而且]})三种括号都有, 哈哈.
            }
          }
        }
      }
    })
  ]);
})();
对啊,如果是开始括号不独立的话,手头上又不带染色IDE的话就要死人了。
LeeNux
LeeNux
eclipse里 ctrl shift f,不喜欢的你自己按一遍自动调!
返回顶部
顶部