要解决的问题
- 复用其他人的工作
- 不依赖二进制接口
- 完整的类型信息保留
解决方案
编程语言基本上都有把源代码拆分成多个source library来编写的能力。 编译的时候把多个source library定义的逻辑编译成一个或者多个object文件。 把 compiler 在这个过程里扮演的角色称之为 source library linker
构成
| 构成 | 解释 |
|---|---|
| source library | 源代码库 |
| object | 多个 source library 一步到位合并成一个 object,或者变成多个有链接关系的 object |
| source library linker | 一般就是编译器自身 |
解决方案案例
tsc
src/main.ts
import {data} from './lib' // referenced source library
import * as unique from 'uniq' // referenced static library
console.log(unique(data));src/lib.ts
export let data = [1, 2, 2, 3, 4, 5, 5, 5, 6]build.sh
# 用 AMD 的格式输出 object 文件
# main.ts 和 lib.ts 被链接成一个 object.js
tsc --outFile dist/object.js --module amd src/main.ts
dist/object.js
define("lib", ["require", "exports"], function (require, exports) {
"use strict";
exports.__esModule = true;
exports.data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
});
define("main", ["require", "exports", "lib", "uniq"], function (require, exports, lib_1, unique) {
"use strict";
exports.__esModule = true;
console.log(unique(lib_1.data));
});
| 构成 | 对应 |
|---|---|
| source library | .ts 文件 |
| static library | CJS / AMD / ES6 Module |
| object | 合并成 .js 文件 |
| source library linker | tsc |
go
go.mod
module example.com/a/example
require github.com/thoas/go-funk v0.0.0-20181020164546-fbae87fb5b5c
main.go
package main
import (
"example.com/a/example/lib"
"fmt"
"github.com/thoas/go-funk"
)
func main() {
fmt.Println(funk.Uniq(lib.Data))
}
lib/lib.go
package lib
var Data = []int{1, 2, 2, 3, 4, 5, 5, 5, 6}build.sh
# 因为 example.com/a/example 所以会产生 example 为名字的二进制可执行文件
go build
| 构成 | 对应 |
|---|---|
| source library | 包含 .go 文件的目录 |
| static library | 其他包含 .a 文件的目录 |
| object | 产生的二进制可执行文件 |
| source library linker | go |