模块与导入
一个文件就是一个模块
每个 .cp 文件就是一个模块,不需要声明模块名。模块之间通过 daochu(导出 / export)和 daoru(导入 / import)共享函数。
导出
函数默认只在本文件里可见。加上 daochu,其他文件才能导入:
cpro
// util.cp
daochu hs double(x z64) z64 { fanhui x * 2 } // 对外可见
hs helper(x z64) z64 { fanhui x + 1 } // 只在本文件可见cpro
// util.cp
导出 函数 double(x i64) i64 { 返回 x * 2 } // 对外可见
函数 helper(x i64) i64 { 返回 x + 1 } // 只在本文件可见cpro
// util.cp
export fn double(x i64) i64 { return x * 2 } // 对外可见
fn helper(x i64) i64 { return x + 1 } // 只在本文件可见- 只有函数能跨文件使用,模块级变量不能导出
- 结构体不能导出,但可以导出返回结构体的函数,调用方用变量接住即可
导入
导入本地文件
按名字导入,用 laizi(来自 / from)指定文件,导入后直接用函数名调用:
cpro
daoru { double } laizi "./util.cp"
rukou() {
dayin(double(21)) // 42
}cpro
导入 { double } 来自 "./util.cp"
入口() {
打印(double(21)) // 42
}cpro
import { double } from "./util.cp"
rukou() {
print(double(21)) // 42
}整个文件导入,之后用 文件名.函数名 调用:
cpro
daoru "./util.cp"
rukou() {
dayin(util.double(21)) // 42
}cpro
导入 "./util.cp"
入口() {
打印(util.double(21)) // 42
}cpro
import "./util.cp"
rukou() {
print(util.double(21)) // 42
}- 路径相对当前文件所在目录,必须以
./或../开头,必须带.cp扩展名 - 路径分隔符一律用
/,Windows 上也一样 - 文件名大小写必须和磁盘上完全一致
起别名
两个文件有同名函数时,用 zuowei(作为 / as)改名:
cpro
daoru { open zuowei open_file } laizi "./file.cp"
daoru { open zuowei open_conn } laizi "./conn.cp"cpro
导入 { open 作为 open_file } 来自 "./file.cp"
导入 { open 作为 open_conn } 来自 "./conn.cp"cpro
import { open as open_file } from "./file.cp"
import { open as open_conn } from "./conn.cp"导入标准库
标准库只能整个导入,然后用 模块名.函数名 调用:
cpro
daoru "io"
rukou() {
io.cuowu_dayin("写到标准错误")
}cpro
导入 "io"
入口() {
io.eprint("写到标准错误")
}cpro
import "io"
rukou() {
io.eprint("写到标准错误")
}写成 daoru { eprint } laizi "io" 会报错。
字符串模块不需要导入,直接用。部分标准库模块有拼音名,导入时用哪个名字,调用时就用哪个:
| 拼音 | 英文 |
|---|---|
zifuchuan | string |
huanjing | env |
wenjian | fs |
wangluo | net |
| — | io |
| — | http |
cpro
daoru "wenjian" // 之后写 wenjian.xxx(...),不能写 fs.xxx(...)cpro
导入 "wenjian" // 之后写 wenjian.xxx(...),不能写 fs.xxx(...)cpro
import "wenjian" // 之后写 wenjian.xxx(...),不能写 fs.xxx(...)标准库模块名(包括拼音名)是保留的,不能用作变量名、函数名,本地文件也不能叫 io.cp 这样的名字。
导入第三方包
第三方包写全名 发布者/包名,只能按名字导入:
cpro
daoru { add } laizi "zhangsan/math"cpro
导入 { add } 来自 "zhangsan/math"cpro
import { add } from "zhangsan/math"包要先在 cpro.json 里声明并安装,见 使用第三方包。只有自己清单里声明的包才能导入,即使磁盘上装着别的包也不行。
转发导出
daoru 进来的函数默认只在本文件可用。要让它也从本文件对外导出,写 daochu daoru:
cpro
// api.cp
daoru { helper } laizi "./internal.cp" // 仅本文件可用
daochu daoru { double, double zuowei fanbei } laizi "./util.cp" // 对外可见cpro
// api.cp
导入 { helper } 来自 "./internal.cp" // 仅本文件可用
导出 导入 { double, double 作为 fanbei } 来自 "./util.cp" // 对外可见cpro
// api.cp
import { helper } from "./internal.cp" // 仅本文件可用
export import { double, double as fanbei } from "./util.cp" // 对外可见这样可以做一个"门面"文件,把分散在多个文件里的函数集中对外提供。转发要每一层都写 daochu daoru,不会自动往外传。
访问边界
- 不能直接导入标准库的内部文件,只能通过
daoru "模块名"使用 - 不能用相对路径导入第三方包里的文件,只能按名字导入它公开的函数
- 第三方包不能用相对路径导入包外的文件
规则汇总
| 写法 | 结果 |
|---|---|
daoru { f } laizi "./a.cp" | ✓ 本地文件,按名字导入 |
daoru "./a.cp" | ✓ 本地文件,整个导入,之后 a.f() |
daoru "io" | ✓ 标准库,之后 io.f() |
daoru { f } laizi "io" | ✗ 标准库不能按名字导入 |
daoru { f } laizi "zhangsan/pkg" | ✓ 第三方包 |
daoru "zhangsan/pkg" | ✗ 第三方包不能整个导入 |
daoru { f } laizi "a.cp" | ✗ 相对路径要以 ./ 开头 |
daoru { f } laizi "./a" | ✗ 要带 .cp 扩展名 |
导入没有 daochu 的函数 | ✗ |
