Nim编码风格
介绍
Nim语言不限制开发人员使用哪种具体的编码风格,
但为了社区的发展,在编写一些标准库的时候还是应该遵从统一的编码风格
这篇文章会列出一系列的编码风格准则,供大家参考。
但值得注意的是,有很多例外场景会与这些准则相悖,
而且,nim语言非常灵活,在一些特定上下文中,这些编码风格准则也不适用。
跟python相似,python的编码风格在不断演化、改变,
nim语言也是这样,随着时间的推移,这个编码风格准则也会改变。
在编写nim的基础类库、编译器、官方工具的时候,
强制要求遵从这些编码风格准则
间距和空白约定
-
一行的代码量不应该超过80个字符,一行代码量太多的话不利于阅读;
-
应该使用两个空格来制定缩进,不能使用tab按键来制定缩进;这是因为对于不同的编辑器来说,空格所代表的宽度都是一样的,但制表符所代表的宽度可能是不同的;
-
虽然开发人员可以使用空格来格式化代码,但是需要注意的是,并不是所有的编辑器都能完成自动对齐工作;
下面这段代码是不推荐的案例
# 下面这段代码是不推荐的案例, # 如果以后再有人来修改这段代码, # 他有可能需要重新格式化所有的代码: type WordBool* = int16 CalType* = int ... # 5 lines later CalId* = int LongLong* = int64 LongLongPtr* = ptr LongLong
命名约定
注意:下面我们描述的命名约定有可能过一段时间就会过时了。
应该使用PascalCase(两个单词中每个单词首字母都大写)命名法命名类型标识符
另外,除了一些常量可能会使用PascalCase命名法之外,
其他的标识符都应该使用camelCase(两个单词中,第一个单词的首字母小写,第二个单词的首字母大写)
const aConstant = 42 const FooBar = 4.2 #常量类型约束不是那么明显 var aVariable = "Meep" type FooBar = object
对于C/C++的包装器来说,nim语言允许开发人员使用ALL_UPPERCASE的命名方式(所有字符都大写),但这看起来实在太丑了。
当命名值、指针、引用类型时,大部分时候的都是直接用一个有意义的名字即可,
也可以根据情况给这些名字加上“Obj”或“Ref”或“Ptr”后缀
对于C/C++的包装器来说,也遵从这样的原则。
type Handle = int64 # 常用 HandleRef = ref Handle # 不那么常用
对于异常或错误类型的变量,需要加上Error尾缀
type UnluckyError = object of Exception
枚举类型的成员应该有一个确定的前缀,一般情况下都是枚举类型名称的缩写
(如果标记为{.pure.}可以不遵从这项约定)
type PathComponent = enum pcDir pcLinkToDir pcFile pcLinkToFile
non-pure的枚举值应该使用camelCase命名法
pure枚举值应该使用PascalCase命名法
type PathComponent {.pure.} = enum Dir LinkToDir File LinkToFile
对于HTTP HTML FTP TCP IP UTF WWW这类词语来说
没必要左右的字母都大写。parseUrl比parseURL要好很多
checkHttpHeader比checkHTTPHeader要好很多
编码约定
只有在流程控制语句需要的时候,才使用return语句
一般情况下都使用默认的result变量
(别忘了nim语言的每个方法中都有一个隐藏的result变量)
一般情况下推荐返回一个[]或者""或者抛出一个异常,而不是返回一个nil
大部分时候用proc(方法)就能满足业务需求了
只有在比较特殊的时候才会用到宏、模版、迭代器、转换器
如果一个变量在其作用域内不会变化,那么尽量用let声明它,(不要用var声明它)
对于用户自定义类型来说,通常建议同时创建"ref"和"object"类型
多行语句和表达式的约定
如果元组类型的定义,长度超过了一行(80个字符),那么就应该分成多行来定义
type ShortTuple = tuple[a: int, b: string] ReallyLongTuple = tuple wordyTupleMemberOne: string wordyTupleMemberTwo: int wordyTupleMemberThree: double
同样,任何类型的声明,如果长度超过一行,应该格式化多行来声明
type EventCallback = proc ( timeRecieved: Time errorCode: int event: Event )
如果一个方法的参数较多,需要在多行内书写,
那么第二行的开始应该与第一行上的左括号对齐
proc lotsOfArguments(argOne: string, argTwo: int, argThree:float argFour: proc(), argFive: bool): int {.heyLookALongPragma.} =
如果你需要调用一个方法,而调用语句很长的话
你可以把每个参数都分做一行,也可以多个参数占用一行(与第一行的左括号对齐)
# 对于复杂方法调用的时候,推荐每个参数占用一行. readDirectoryChangesW( directoryHandle.THandle, buffer.start, bufferSize.int32, watchSubdir.WinBool, filterFlags, cast[ptr dword](nil), cast[Overlapped](ol), cast[OverlappedCompletionRoutine](nil) ) # 简单方法调用时,推荐:多个参数占用一行,与第一行的左括号对齐 startProcess(nimExecutable, currentDirectory, compilerArguments environment, processOptions)