我刚开始在一家公司工作,在我的第一次代码审阅中,样式注释之一是返回类型和方法名称应该在不同的行上。例如这个
void foo() {
}
应该是这个
void
foo() {
}
我一直使用第一样式,我想知道除了个人喜好之外,还有其他原因为什么人们使用第二样式吗?我认为第一个完全不会影响可读性。在C程序员和大型开源项目中,一种比另一种更普遍吗?
我刚开始在一家公司工作,在我的第一次代码审阅中,样式注释之一是返回类型和方法名称应该在不同的行上。例如这个
void foo() {
}
应该是这个
void
foo() {
}
我一直使用第一样式,我想知道除了个人喜好之外,还有其他原因为什么人们使用第二样式吗?我认为第一个完全不会影响可读性。在C程序员和大型开源项目中,一种比另一种更普遍吗?
Answers:
想知道除了个人喜好之外,还有其他原因导致人们使用第二种风格吗?
这种风格在C的早期就很流行,所以原因可能就是他们很长时间以来一直这样做,他们有很多看起来像这样的代码,这就是原因每个人都习惯了。与其说个人喜好,不如说是公司发展的动力。
另一个原因是函数名称总是始于第一列。返回类型的长度各不相同,并且可能有些复杂-将类型放在自己的行上会使函数名称更易于查找。
如果公司采用固定样式,则他们可能还具有编码标准文档。去问问。它可能会解释选择此选项的原因,并且拥有副本将帮助您避免以后的评论中出现类似问题。
__attribute
s。然后,在研究C ++时,您可能具有相对复杂的返回类型,因此可能必须在其中添加换行符。
^start_of_a_long_func
并立即使用我们要搜索的功能。
这几乎是我发现的唯一一条实际上对可读性产生显着影响的代码格式化规则,并且几乎不需要花力气(假设您的代码编辑器不会与您展开争执)。
好的编程语言设计是使名称在声明/定义中的位置一致。基本原理很简单:您有一个不错的视觉锚(花括号或只是一个悬挂的凹痕),可用于立即查找名称的开头。扫描文件查找名称时,您不必真正解析语言。
这与格式化文档时相同:在开始新的部分时,您将名称以粗体显示(通常在其自己的行上)以粗体显示,而不用一句话掩埋,不加区分。
早期的C具有非常简洁的签名:返回类型是可选的,并且在签名之后声明了参数类型。名称也往往很短。这减轻了偶尔使用返回类型抵消名称的影响。
double dot(x, y);
还是很容易消化的。
C ++使这一点变得更糟。它将参数类型规范移至签名中,从而使签名更长。后来在C的标准化过程中采用了这种语法。
static struct origin *find_origin(struct scoreboard *sb,
struct commit *parent,
struct origin *origin)
较不易消化,但还不错。(摘自Git)
现在考虑使用长的,描述性的名称和参数化的类型的现代编程实践,并了解这种选择是如何造成灾难性的。Boost标头中的示例:
template <class A1, class A2, class A3, class A4, class A5, class A6>
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&)
{
typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
return result_type();
}
如果您正在编写通用代码,则此类签名甚至都不会与众不同。您可以找到比这更糟糕的情况的例子,而不必太努力。
C,C ++及其派生Java和C#似乎是具有可读的声明/定义的例外。他们流行的前辈和同行(Fortran,ALGOL,Pascal)将名称放在结果类型之前,而且值得庆幸的是,他们的许多继任者(Go,Scala,TypeScript和Swift等)也选择了更具可读性的语法。
我大约在19年与C&C ++合作时就遇到了这种风格。对于某人如何发明这种邪恶的东西感到困惑。
我能找到的唯一(潜在的)积极点是,您可以使用grep ^ FuncName找到函子定义。在十年前的某些真正的工具讨厌社区中,它可能是相关因素。在我所看到的地方,它被应用于C ++和类成员函数,甚至杀死了该属性。
猜猜我的意见。:)
grep -P '^(\w+::)?FuncName'