如同写作,写代码也是有代码风格(code style)。不过代码风格和文风不一样,一个人的文风可以随心所欲,代码风格最好是“千篇一律”。它的核心就是:便于阅读。
如果你的代码风格也要随心所欲,那么多年后,你再回顾你以前写的代码,你心中可能只有一个疑问:
这TMD是谁写!!!
当然别人也是这样想的,所以为了世界和平,请保持你的代码风格符合一定规则。这里,我们学习的是多个知名R包(dplyr, ggplot2)开发者Hadley大神推荐的代码风格。
对象名(Object names)
每次写代码的时候,我总要纠结,这个变量叫啥名字,那个函数又要叫啥名字,于是半天过去了,代码居然一行都没写好。命名比较推荐的是用_分割不同单词,比如说code_style。当然驼峰式命名 codeStyle 也行, 只要保证前后一致。如果你英文水平不错,还可以让变量名都是名词,函数名都是动词。
记住: 千万不要把内置的函数名或变量名用于命名,比如说TRUE <- FALSE
。如果你老板对你太狠,你不想干了,倒是可以考虑一下。
合理使用空格
什么叫做合理使用空格呢? 其实就是在所用能用空格的地方都用上空格,比如说
# 反面教材
average<-mean(feet/12+inches,na.rm=TRUE)
完全就可以改成
# 学习模范
average <- mean(feet / 12 + inches, na.rm = TRUE)
前后比较一下,你就会发现后者的阅读更加舒服,没有那么拥挤。但是不要过度, 但是你应该不会这样做。
# 过犹不及
average <- mean ( feet / 12 + inches, na.rm = TRUE )
不过如果是判断语句,比如说if, 那么在 () 前后增加空格就是合理的。
# 反面教材
if(debug)do(x)
plot (x, y)
# 学习模范
if (debug) do(x)
plot(x, y)
关于花括号
我们先看一个反面教材和学习模范的对比:
# 反面教材
if (y < 0 && debug)
message("Y is negative")
if (y == 0)
{ log(x) }
else
{y ^ x}
# 学习模范
if (y < 0 && debug) {
message("Y is negative")
}
if (y == 0) {
log(x)
} else {
y ^ x
}
有没有发现,合理的花括号的使用可以 非常清楚 得找到条件语句中的执行部分,并且代码更容易阅读。简单来说就是如下两点:
- { 不要独立成行
- } 尽量独立成行,除非后面紧跟else
每一行的长度
每一行的长度不要超过80个字符,这样子在印刷的时候,可以调整合适的字体大小。什么,你不知道80个字符是多少? 没事,Rstudio可以用 Ctrl + Shift + \ 进行重排。或者每次你觉得自己的代码写的太挤了,就另起一行吧。
每行缩进
千万不要混用Tab和space,甚至就不要用Tab进行缩进, 千万不要,记住千万不要。因为不同系统对Tab所占空白区域是不同的,对于Python而言,混用直接出错。
至于每一行缩进多少就按照你自己喜欢的来,Rstuido默认是2个空格,我觉得挺好看的。
赋值
请用 <- 对变量赋值,不要用=, =仅仅用在函数里面的参数赋值。有一次我看到别人代码里面通篇用=进行赋值,我知道他之前学编程用的是Perl, 所以会把这些习惯带过来。但是既然用了R, 那么爱屋及乌用<-吧!
# 反面教材
x = 123
# 学习模范
x <- 123
PS: 这条不是必须的,但是强烈推荐,这样子别人立马能看出来你写的是R代码。当然我已经能够熟练在Python和R里面切换使用赋值符号了。
请用注释
如果这个代码这辈子都不用第二次了,也不打算给任何人看,那么你不需要写注释。否则,请写上你的注释,并且保证你的注释有意义,也就是解释你为什么要写这行代码,而不只是说这行代码干了什么
## 反面教材
# 往屏幕输出"hello world"
print("hello world")
## 学习模范
# 为了让初学者体验编码非常简单,用"hello world"的方式和计算机交互
print("hello world")
最后,如果你已经写了大量风格迥异的代码,不想一个个修改怎么办?好在谢益辉大神写了fromatR帮助我们调整编码风格:
# install.packages("formatR")
# 用法
formatR::tidy_dir("R")
这个包主要完成了如下内容,基本上完全按照代码风格修改:
- 单行代码和注释过长会被重新组织成多行,更加容易阅读
- 尽可能地增加空格和缩进
- 大多数情况下会保留注释
- 缩进默认空格为4个, 但是可以修改
- 单行无}的else会被放回前一行
- 赋值操作的=会被替换成<-, 函数参数中=不在考虑范围内
- { 可以移到新的一行中。
当然谢益辉大神在博客(地址为https://yihui.name/formatr/)里也详细接好了formatR
注: 还可以用linter可以在写代码时检查潜在问题。