跳到主要内容

项目结构

小型 White 程序不需要项目清单。wlc 从一个入口文件开始,并沿着其中的 import 读取其他源码,因此单文件项目只需要:

hello/
└── main.wl

在项目目录中编译:

wlc main.wl

没有使用 -o 时,可执行文件会写在 main.wl 旁边。会产生多个输出的项目可以 使用单独的构建目录,避免生成文件与源码混在一起:

wlc src/main.wl -o build/app

build 目录需要事先创建。

多个源文件

导入本地 White 文件时需要明确写出 .wl 后缀:

hello/
├── main.wl
└── greeting.wl
greeting.wl
func message(name: String) -> String {
return "hello, " + name;
}
main.wl
import "greeting.wl"

func main() -> Int {
print(greeting.message("White"));
return 0;
}

普通模块导入会用文件名建立命名空间。导入只在写出它的源文件中可见:某个模块 导入了 greeting.wl,并不会让整个程序都能直接使用 greeting

路径以执行 import 的文件为基准解析,而不是以启动 wlc 时碰巧所在的目录为基准。 因此从其他目录调用编译器时,项目内部导入仍能保持不变。

目录包

目录中存在 _pkg.wl 时,它可以作为包导入。这个文件负责定义包的公开结构:

hello/
├── main.wl
└── model/
├── _pkg.wl
└── user.wl
model/user.wl
class User {
let name: String;

init(name: String) {
self.name = name;
}
}
model/_pkg.wl
import User from "user.wl"
main.wl
import "model"

func main() -> Int {
let user: model.User = model.User("White");
print(user.name);
return 0;
}

_pkg.wl 中,具名导入会通过包重新导出该符号;import * from "file.wl" 会重新导出文件中的全部公开符号;普通的 import "file.wl" 则保留子模块命名空间。 普通源文件不会重新导出自己导入的内容。

__ 开头的名称是私有名称,不能跨越模块或包边界导入。

标准库导入

标准库包和文件从 WL_PATH/std 查找,导入时不写 .wl 后缀:

import "file"
import "json"
import "strings"
import "sys"

这与 import "parser.wl" 这样的本地文件导入不同。后缀明确表示路径指向一个源码 文件,而不是标准模块或目录包。

builtin、标准 Error 类型与 Dict 支持会接入 prelude,因此代码可以直接使用 其中的非限定名称。需要 builtin.print(...) 这样的限定调用时,仍然可以明确写出 import "builtin"

std/internal 只供标准库实现使用,用户项目无法导入该目录。