对于变量命名的建议,Dart 这个 文档 写得非常好。下面大部分内容摘录自此。
保持一致
好的命名:
pageCount // A field.
updatePageCount() // Consistent with pageCount.
toSomething() // Consistent with Iterable's toList().
asSomething() // Consistent with List's asMap().
Point // A familiar concept.
差的命名:
renumberPages() // Confusingly different from pageCount.
convertToSomething() // Inconsistent with toX() precedent.
wrappedAsSomething() // Inconsistent with asX() precedent.
Cartesian // Unfamiliar to most users.
最重要的描述性名词放最后面
好的命名:
pageCount // A count (of pages).
ConversionSink // A sink for doing conversions.
ChunkedConversionSink // A ConversionSink that's chunked.
CssFontFaceRule // A rule for font faces in CSS.
差的命名:
numPages // Not a collection of pages.
CanvasRenderingContext2D // Not a "2D".
RuleFontFaceCss // Not a CSS.
最重要的描述性名词放最后面
好的命名:
pageCount // A count (of pages).
ConversionSink // A sink for doing conversions.
ChunkedConversionSink // A ConversionSink that's chunked.
CssFontFaceRule // A rule for font faces in CSS.
差的命名:
numPages // Not a collection of pages.
CanvasRenderingContext2D // Not a "2D".
RuleFontFaceCss // Not a CSS.
非布尔型的属性或变量,用名词短语来命名
好的命名:
list.length
context.lineWidth
quest.rampagingSwampBeast
差的命名:
list.deleteItems
boolean 属性或变量,用非命令式动词短语
boolean 变量经常被用在控制流的条件中,所以用动词短语可读性好于形容词。比较下这两者:
if (window.closeable) ... // Adjective.
if (window.canClose) ... // Verb.
非命令式动词短语(non-imperative verb phrase)有几种:
- "to be" 形式:
isEnabled
,wasShown
,willFire
等 - 助动词:
hasElements
,canClose
,shouldConsume
,mustSave
等
非命令式动词短语,它从语义上不改变任何东西,因此适合作为属性的命名,因为访问一个 boolean 变量也不改变任何东西。
好的命名:
isEmpty
hasElements
canClose
closesWindow
canShowPopup
hasShownPopup
差的命名:
empty // Adjective or verb?
withElements // Sounds like it might hold elements.
closeable // Sounds like an interface.
// "canClose" reads better as a sentence.
closingWindow // Returns a bool or a window?
showPopup // Sounds like it shows the popup.
当函数参数为 boolean 时,省略掉动词
这个修订了上一条建议。boolean 作为参数时,往往是比较直观的,省略掉动词会简练一些:
Isolate.spawn(entryPoint, message, paused: false);
var copy = List.from(elements, growable: true);
var regExp = RegExp(pattern, caseSensitive: false);
用「正向」形式来表达 boolean 属性或变量
好的例子:
if (socket.isConnected && database.hasData) {
socket.write(database.read());
}
差的例子:
if (!socket.isDisconnected && !database.isEmpty) {
socket.write(database.read());
}
例外:有些场景下,反向形式是最常被使用的(比如有时候关注反向多于正向),此时用反向更佳。
用于返回数值的函数命名
使用名词短语:
var element = list.elementAt(3);
var first = list.firstWhere(test);
var char = string.codeUnitAt(4);
避免函数命名为 getXXX
如果函数不带参数,它的作用类似于访问一个属性,可以设置一个 getter。比如 getBreakfastOrder()
变为 breakfastOrder
属性。
如果函数需要带参数、或者有副作用等导致它不能被定义成一个 getter,可以选择:
- 去掉
get
,使用名词短语,比如breakfastOrder()
- 使用更精确的动词,如
create
,download
,fetch
,calculate
,request
,aggregate
等
生成格式字符串
比如你想动态生成一个 Redis key:
def get_session_key(session_id):
return f"session_{session_id}"
这个函数命名中的 get
会使其含意混淆不清,直觉会认为是从远程接口获取的。好的命名应该叫 make_session_key
。这个命名参考了 django-redis 项目的某段 代码。