data Tree a
= Node {left: Tree, right: Tree}
| Leaf {value: a}
我遇到了两个问题:1、我没能找到一种方法来创建具有多个构造函数的类型,所以我必须将所有数据都放在一个构造函数中。2、我无法使其多态化,因此我只能使用 interface{}
(我猜这是对类型系统的“放弃”?)。这是我能做到的最好程度:
package main
import ("fmt")
type Tree struct {
IsLeaf bool
Left *Tree
Value interface{}
Right *Tree
}
func build(n int) *Tree {
if (n == 0) {
return &Tree{IsLeaf: true, Left: nil, Value: 1, Right: nil}
} else {
return &Tree{IsLeaf: false, Left: build(n - 1), Value: 0, Right: build(n - 1)}
}
}
func sum(tree *Tree) int {
if (tree.IsLeaf) {
return tree.Value.(int)
} else {
return sum(tree.Left) + sum(tree.Right)
}
}
func main() {
fmt.Println(sum(build(23)))
}
它实现了类型并通过对生成的大树求和来测试它。我已经在JavaScript中进行了等效实现(包括构造函数上的冗余数据,以保证公平性):
const build = n => {
if (n === 0) {
return {IsLeaf: true, Value: 1, Left: null, Right: null};
} else {
return {IsLeaf: false, Value: 0, Left: build(n - 1), Right: build(n - 1)};
}
}
const sum = tree => {
if (tree.IsLeaf) {
return tree.Value;
} else {
return sum(tree.Left) + sum(tree.Right);
}
}
console.log(sum(build(23)));
我已经使用
go build test.go
编译了Go代码,使用time ./test
运行了它。我使用node test.js
运行了Node.js代码。经过多次测试,Go程序平均运行时间约为2.5
秒,而Node.js程序平均运行时间约为1.0
秒。
这意味着对于这个简单的程序,Go要比Node.js慢2.5倍
,但这显然是不正确的,因为Go是一种静态类型、编译语言,拥有成熟的编译器,而JavaScript则是一种未经类型检查的解释型语言。
那么我的Go程序为什么会这么慢呢?我是否遗漏了某些编译选项,或者代码本身存在问题?