【发布时间】:2010-09-17 05:54:20
【问题描述】:
- 您使用什么规则来命名变量?
- 哪些地方允许使用单字母变量?
- 您在名称中输入了多少信息?
- 示例代码怎么样?
- 您首选的无意义变量名是什么? (在 foo & bar 之后)
- 为什么拼写为"foo" and "bar" 而不是FUBAR
【问题讨论】:
标签: language-agnostic naming conventions
【问题讨论】:
标签: language-agnostic naming conventions
我会说尽量清楚地命名它们。永远不要使用单字母变量,如果您只是在测试某些东西(例如,在交互模式下)并且不会在生产中使用它,则只使用 'foo' 和 'bar'。
【讨论】:
本地人:fooBar; 成员/类型/函数 FooBar 接口:IFooBar
对于我来说,单字母只有在名字是经典的情况下才有效; i/j/k 仅用于局部循环索引,x,y,z 用于向量部分。
变量的名称可以传达含义,但足够短,不会换行
foo,bar,baz。泡菜也是最爱。
【讨论】:
我喜欢为变量添加前缀:str = String、int = Integer、bool = Boolean 等。
在循环中使用单个字母既快速又简单:For i = 0 to 4...Loop
变量是一种简短但描述性的替代您正在使用的内容。如果变量太短,您可能无法理解它的用途。如果太长,您将永远为代表 5 的变量键入内容。
Foo & Bar 用于示例代码以显示代码的工作方式。您可以使用几乎任何不同的无意义字符来代替。我通常只使用 i、x 和 y。
我个人对 foo bar 与 fu bar 的看法是太明显了,没有人喜欢 2 字符变量,3 更好!
【讨论】:
function startEditing(){
if (user.canEdit(currentDocument)){
editorControl.setEditMode(true);
setButtonDown(btnStartEditing);
}
}
应该像叙事作品一样阅读。
【讨论】:
这一切都取决于您正在开发的语言。由于我目前使用的是 C#,因此我倾向于您使用以下语言。
变量的camelCase。
camelCase 参数。
属性的 PascalCase。
成员变量的m_PascalCase。
单字母 vars 允许在哪里? 我倾向于在 for 循环中执行此操作,但每当我这样做时都会感到有点内疚。但是对于 foreach 和 lambda 表达式,for 循环现在并不常见。
你在名字中输入了多少信息?
如果代码有点难以理解,请写评论。不要将变量名变成注释,即 .
int theTotalAccountValueIsStoredHere
不是必需的。
你喜欢什么无意义的变量名? (在 foo & bar 之后) 我或 x。 foo 和 bar 对我来说有点过于大学教科书的例子了。
为什么它们拼写为“foo”和“bar”而不是 FUBAR? 传统
【讨论】:
for(int i = 0; i< endPoint; i++) {...} int max( int a, int b) { if (a > b) return a; return b; }
【讨论】:
在 DSL 和其他流畅的接口中,变量名和方法名通常一起构成一个词法实体。例如,我个人喜欢(公认的异端)命名模式,其中动词放在变量名而不是方法名中。 @见6th Rule of Variable Naming
另外,我喜欢简洁地使用$ 作为一段代码的主要变量的变量名。例如,漂亮地打印树结构的类可以将$ 用于 StringBuffer inst var。 @见This is Verbose!
否则我参考 Einar Hoest 的程序员手册。 @见http://www.nr.no/~einarwh/phrasebook/
【讨论】:
你使用什么规则来命名你的变量?我已经在单词之间的下划线 (load_vars)、驼峰式大小写 (loadVars) 和无空格 (loadvars) 之间切换。类总是 CamelCase,大写。
单字母变量允许在哪里? 循环,主要是。一次性代码中的临时变量。
您在名称中输入了多少信息? 足以在我编码时提醒我它是什么。 (是的,这可能会导致以后出现问题!)
你喜欢什么无意义的变量名? (在 foo & bar 之后) temp, res, r.我实际上并没有大量使用 foo 和 bar。
【讨论】:
更新
首先,命名取决于现有的约定,无论是来自语言、框架、库还是项目。 (在罗马时...) 示例:将 jQuery style 用于 jQuery 插件,将 Apple style 用于 iOS 应用程序。前一个示例需要更多的警惕(因为 JavaScript 可能会变得混乱并且不会自动检查),而后一个示例更简单,因为该标准得到了很好的执行和遵循。 YMMV 取决于领导者、社区,尤其是工具。
我将抛开我所有的命名习惯以遵循任何现有的约定。
总的来说,我遵循这些原则,所有这些都围绕着编程作为另一种形式的通过书面语言进行的人际交流。
可读性 - 重要部分应该有可靠的名称;但这些名称不应替代intent 的正确文档。代码可读性的测试是你是否可以在几个月后回到它,并且仍然足够理解,不会在第一印象中折腾整个事情。这意味着避免缩写;见the case against Hungarian notation。
可写性 - 公共区域和样板文件应该保持简单(尤其是在没有 IDE 的情况下),这样代码编写起来更容易、更有趣。这有点受Rob Pyke's style的启发。
可维护性 - 如果我像 arrItems 这样将类型添加到我的名字中,那么如果我将该属性更改为扩展 @ 的 CustomSet 类的实例,那就太糟糕了987654327@。类型注释应保存在文档中,并且仅在适当的情况下(用于 API 等)。
标准、通用命名 - 对于哑环境(文本编辑器):类应该在 ProperCase 中,变量应该很短,如果需要,在 snake_case 中,函数应该是在camelCase。
对于 JavaScript,这是语言限制和影响命名的工具的经典案例。它有助于通过不同的命名区分变量和函数,因为没有 IDE 可以握住您的手,而 this 和 prototype 和其他样板文件会模糊您的视野并混淆您的区分技能。一个范围内所有不重要的或全局派生的变量都被缩写也很常见。该语言没有import [path] as [alias];,因此本地变量成为别名。然后是大量不同的空白约定。这里(以及任何地方,真的)唯一的解决方案是正确记录意图(和身份)。
另外,语言本身是基于函数级作用域和闭包的,所以这种灵活性可以使具有 2 个以上作用域级别的变量的块感觉非常混乱,所以我已经看到命名 _ 为每个范围链中的级别到该范围中的变量。
【讨论】:
我总是在 for 循环中使用单字母变量,它看起来更美观且更易于阅读。
这很大程度上取决于您编程的语言,我在 C++ 中命名变量的方式与在 Java 中不同(Java 更适合 imo 过长的变量名,但这可能只是个人喜好。或者它可能与 Java 内置函数的命名方式有关......)。
【讨论】:
我始终遵循的一条规则是:如果一个变量以某些特定单位编码一个值,那么这些单位必须是变量名称的一部分。示例:
int postalCodeDistanceMiles;
decimal reactorCoreTemperatureKelvin;
decimal altitudeMsl;
int userExperienceWongBakerPainScale
我不会对任何火星着陆器的崩溃(或我无聊的 CRUD 业务应用程序中的等效故障)负责。
【讨论】:
在我的 VB3 时代,我学会了永远不要使用单字母变量名。问题是,如果你想在任何使用变量的地方搜索,搜索单个字母有点困难!
较新版本的 Visual Studio 具有智能变量搜索功能,可以避免这个问题,但旧习惯等等。无论如何,我宁愿在荒谬的一面犯错。
for (int firstStageRocketEngineIndex = 0; firstStageRocketEngineIndex < firstStageRocketEngines.Length; firstStageRocketEngineIndex++)
{
firstStageRocketEngines[firstStageRocketEngineIndex].Ignite();
Thread.Sleep(100); // Don't start them all at once. That would be bad.
}
【讨论】:
您使用什么规则来命名变量?
单字母变量允许在哪里?
你在名字中输入了多少信息?
示例代码怎么样?
您首选的无意义变量名是什么? (在 foo & bar 之后)
为什么它们拼写为“foo”和“bar”而不是 FUBAR
【讨论】:
几乎每一种被广泛使用的现代语言都有自己的编码标准。这是一个很好的起点。如果所有其他方法都失败了,请使用推荐的任何方法。当然也有例外,但这些是一般准则。如果您的团队更喜欢某些变化,只要您同意它们,那也没关系。
但归根结底,这不一定是您使用的标准,而是您首先拥有这些标准并遵守这些标准的事实。
【讨论】:
这些都是 C# 约定。
变量名大小写
大小写表示范围。 Pascal 大小写变量是所属类的字段。骆驼大小写变量是当前方法的局部变量。
我只有一个前缀字符约定。类属性的支持字段是 Pascal 大小写的,并带有下划线前缀:
private int _Foo;
public int Foo { get { return _Foo; } set { _Foo = value; } }
我在那里看到了一些 C# 变量命名约定 - 我很确定这是一份 Microsoft 文档 - 强烈反对使用下划线前缀。这对我来说似乎很疯狂。如果我查看我的代码并看到类似
_Foo = GetResult();
我问自己的第一件事是,“我是否有充分的理由不使用属性访问器来更新该字段?”答案通常是“是的,你最好在开始乱搞这段代码之前知道那是什么。”
单字母(和短)变量名
虽然我倾向于同意变量名应该有意义的格言,但在实践中,在很多情况下,使变量名有意义不会增加代码的可读性或可维护性。
循环迭代器和数组索引是使用短且任意变量名的明显地方。不太明显,但在我的书中同样适用的是 nonce 用法,例如:
XmlWriterSettings xws = new XmlWriterSettings();
xws.Indent = true;
XmlWriter xw = XmlWriter.Create(outputStream, xws);
来自 C# 2.0 代码;如果我今天写,当然就不需要 nonce 变量了:
XmlWriter xw = XmlWriter.Create(
outputStream,
new XmlWriterSettings() { Indent=true; });
但是在 C# 代码中仍然有很多地方我必须创建一个对象,你只是要传递到其他地方然后扔掉。
在这种情况下,许多开发人员会使用 xwsTemp 这样的名称。我发现Temp 后缀是多余的。我在其声明中将变量命名为 xws(并且我只在该声明的可视范围内使用它;这很重要)这一事实告诉我它是一个临时变量。
我将使用短变量名的另一个地方是在大量使用单个对象的方法中。这是一段生产代码:
internal void WriteXml(XmlWriter xw)
{
if (!Active)
{
return;
}
xw.WriteStartElement(Row.Table.TableName);
xw.WriteAttributeString("ID", Row["ID"].ToString());
xw.WriteAttributeString("RowState", Row.RowState.ToString());
for (int i = 0; i < ColumnManagers.Length; i++)
{
ColumnManagers[i].Value = Row.ItemArray[i];
xw.WriteElementString(ColumnManagers[i].ColumnName, ColumnManagers[i].ToXmlString());
}
...
如果我给 XmlWriter 一个更长的名称,世界上没有任何方法可以使代码更易于阅读(或更安全地修改)。
哦,我怎么知道xw 不是临时变量?因为我看不到它的声明。我只在声明的 4 或 5 行内使用临时变量。如果我需要一个用于更多代码的代码,我要么给它一个有意义的名称,要么将使用它的代码重构为一种方法——嘿,真是巧合——将短变量作为参数。
您在名称中输入了多少信息?
够了。
结果证明这是一种黑色艺术。我不必在名称中包含大量信息。我知道变量何时是属性访问器的支持字段、临时变量或当前方法的参数,因为我的命名约定告诉我这一点。所以我的名字没有。
这就是它不那么重要的原因。
在实践中,我不需要花费太多精力来找出变量名。我把所有的认知努力都放在了命名类型、属性和方法上。这比命名变量要大得多,因为这些名称通常在范围内是公共的(或至少在整个命名空间中可见)。命名空间中的名称需要以相同的方式传达含义。
这段代码中只有一个变量:
RowManager r = (RowManager)sender;
// if the settings allow adding a new row, add one if the context row
// is the last sibling, and it is now active.
if (Settings.AllowAdds && r.IsLastSibling && r.Active)
{
r.ParentRowManager.AddNewChildRow(r.RecordTypeRow, false);
}
属性名称几乎使注释变得多余。 (几乎。实际上有一个原因将该属性称为AllowAdds 而不是AllowAddingNewRows 进行了很多思考,但它不适用于这段特定的代码,这就是为什么会有评论。)变量名?谁在乎?
【讨论】:
如何命名变量几乎不重要。你真的不需要任何规则,除了那些由语言指定的规则,或者至少是你的编译器强制执行的规则。
选择你认为你的队友能认出的名字被认为是礼貌的做法,但风格规则并没有人们想象的那么有帮助。
【讨论】:
您使用什么规则来命名变量?
通常,由于我是 C# 开发人员,我遵循 IDesign C# Coding Standard 指定的变量命名约定有两个原因
1) 我喜欢它,并且觉得它易于阅读。 2) 这是我这些天广泛使用的Code Style Enforcer AddIn for Visual Studio 2005 / 2008 附带的默认值。
单字母 vars 允许在哪里?
有几个地方我会允许单字母变量。通常这些是简单的循环索引器,或 X、Y、Z 坐标等数学概念。除此之外,从来没有! (我在其他任何地方都使用过它们,我在重读代码时通常会被它们咬伤)。
您在名称中输入了多少信息?
足以准确地知道变量的用途。正如罗伯特·马丁所说:
变量、函数或 上课,应该回答所有大问题 问题。它应该告诉你为什么 存在,它做什么,以及它是如何 用过的。如果名称需要注释, 那么这个名字并没有透露它的 意图。 来自清洁代码 - 敏捷软件工艺手册
【讨论】:
我遵守的规则是;
名称是否完整准确地描述了变量所代表的内容?
这个名称是指现实世界的问题而不是编程语言的解决方案吗?
这个名字是否足够长以至于你不必把它弄明白?
计算值限定符(如果有)是否位于名称的末尾?
它们是否只在需要时才具体实例化?
【讨论】:
我现在做了很多 php,但并不总是这样,在变量命名方面我学到了一些技巧。
//这是我的字符串变量 $strVar = "";
//这将表示一个数组 $arrCards = 数组();
//这是一个整数 $intTotal = NULL:
//对象 $objDB = new database_class();
//布尔值 $blValid = 真;
【讨论】:
由于我是一名承包商,在不同的公司和项目之间工作,我更喜欢避免自定义命名约定。它们使新开发人员或维护开发人员更难熟悉(并遵循)正在使用的标准。
因此,虽然人们可以在其中找到不同意的地方,但我希望 the official Microsoft Net guidelines 获得一组一致的命名约定。
除了一些例外(匈牙利符号),我认为一致的用法可能比任何任意规则集更有用。也就是说,每次都以相同的方式进行。
.
【讨论】:
您使用什么规则来命名变量? CamelCase 用于所有重要变量,CamelCase 用于所有类
单字母 vars 允许在哪里? 在单字母 var 名称与数学定义一致的循环构造和数学函数中。
你在名字中输入了多少信息? 你应该能够像阅读一本书一样阅读代码。函数名称应该告诉您函数的作用(scalarProd()、addCustomer() 等)
示例代码怎么样?
你喜欢什么无意义的变量名? (在 foo & bar 之后) temp、tmp、input,我从来没有真正使用过 foo 和 bar。
【讨论】:
我从不使用像 foo 或 bar 这样无意义的变量名,当然,除非代码真的被丢弃了。
对于循环变量,我将字母加倍,以便更容易在文件中搜索变量。例如,
for (int ii=0; ii < array.length; ii++)
{
int element = array[ii];
printf("%d", element);
}
【讨论】:
【讨论】:
我在 MathCAD 工作,我很高兴,因为 MathCAD 在命名方面为我提供了难以置信的可能性,而且我经常使用它们。如果没有这个,我无法理解如何编程。 为了区分一个变量和另一个变量,我必须在名称中包含很多信息,例如:
1.首先——就是数量-N,力F等等
2.在第二个 - 附加索引 - 例如力的方向
3.在第三个 - 向量或矩阵 var 内的索引,为方便起见,我将 var 名称放在 {} 或 [] 括号中以显示其尺寸。
所以,作为结论,我的 var 名称就像 N.dirs / Fx i.row / {F}.w.(i,j.k) / {F}.w.(k,i.j)。 有时我必须为向量值添加坐标系的名称 {F}.{GCS}.w.(i,j.k) / {F}.{LCS}.w.(i,j.k)
作为最后一步,我在外部函数的末尾以粗体添加外部模块的名称或像 Row.MTX.f([M]) 这样的 var,因为 MathCAD 没有函数的帮助字符串。
【讨论】: