Julia SciML 风格指南
理念
- 编写尽可能宽泛的函数、尽可能广泛的测试
- 但是,编写尽可能具体的类型
- 编写类型稳定(从输入类型推导输出类型)和类型接地(从输入类型推导函数中的每个类型)的函数
- 函数内部处理的类型应该和输入类型一致
- 尽可能与 Julia 语言内部的通过多重派发实现的各种接口保持一致
- 宏只用于语法糖,不用于实现更复杂的功能
- 通过发布子包的方式避免条件调用模块
- 函数尽可能是不可变的
- 函数要么是不可变的,要么是不分配新空间的
- 在模块中避免全局变量
- 避免闭包,使用 Fix 等方法替代
- 每个函数只做一件事情
- 不要定义可能在别的地方出现的函 数
具体规则
命名
- 类型、模块用大驼峰命名法
- 函数、变量用小蛇命名法
- 常量用大蛇命名法
- 类型变量用单个大写字母
- 用完整单词而非缩写
- 用两个下划线表明私有方法
- 不在公开接口中使用 Unicode
注释
- 能用命名体现的就不用注释
- 用 TODO 和 XXX 表明没有实现的和有问题的代码
- 用
code
来体现代码 - 用 URL 表示 GitHub 议题和拉取请求
- 在代码的上面写注释,而非在行内
模块
- 先写
import
,再写using
- 在模块中只应该用
import
和using X: x
- 导出变量时应该尽量唯一
- 含有模块的代码不应该含有其他东西
函数
- 只在一行能写下的情况下用短形式
- 没有默认值的应该作为位置参数
- 用命名元组来批量传送关键字参数
- 避免类型海盗:给不属于自己的类型和函数添加方法
- 函数参数顺序
- 函数
- I/O
- 被改变的输入
- 类型
- 没被改变的输入
- 键
- 值
- 其他
- 可变参数
- 关键字
测试
- 使用
@safetestset
- 测试需要能够独立重现
- CI 需要包括当前版本和 LTS
文档
- 包括一个简短的教程,能够覆盖 90% 使用场景,展现一个完整的工作流,并且注意变量命名
- 用 docstring 来生成 API 文档
- 尽可能展示方法而非字段,不展示的字段不视为接口
- 只需要展示那些导出的函数
- 避免展示过于常见的重载函数
- 展示一个函数而非具体的方法
- 用
@doc
,doc"""..."""
来编写 LaTeX - 可以在一个 docstring 中展示多个方法,但只对自己定义的函数这么做
模板
"""
MyArray{T, N}
My super awesome array wrapper!
## Fields
- `data::AbstractArray{T, N}`: stores the array being wrapped
- `metadata::Dict`: stores metadata about the array
"""
struct MyArray{T, N} <: AbstractArray{T, N}
data::AbstractArray{T, N}
metadata::Dict
end
"""
mysearch(array::MyArray{T}, val::T; verbose = true) where {T} -> Int
Searches the `array` for the `val`. For some reason we don't want to use Julia's
builtin search :)
## Arguments
- `array::MyArray{T}`: the array to search
- `val::T`: the value to search for
## Keywords
- `verbose::Bool = true`: print out progress details
## Returns
- `Int`: the index where `val` is located in the `array`
## Throws
- `NotFoundError`: I guess we could throw an error if `val` isn't found.
"""
function mysearch(array::AbstractArray{T}, val::T) where {T}
...
end