go语言多文件运行技巧
有两个源码文件的go语言项目如何运行?
go.mod
main.go
Trie.go
如何直接运行go run main.go
会提示找不到文件。
# 在windows10下运行
$ go run main.go
# command-line-arguments
.\main.go:6:9: undefined: Constructor
是真的找不到文件吗。其实不是。我们把鼠标放到Constructor()函数上就会发现main.Constructor
也就这个函数在代码结构中的路径,而且这个函数是大写字母开头的。所以应该是我们的命令有问题。在传统的c/c++
项目中,都是先编译才能运行的。go语言作为一门静态语言,也应当如此。这里提供四种方法
# 在windows
go run ./
# 在linux
go run *.go
# 通用
go run main.go Trie.go
# 先编译,再运行
go build
.\m.exe
go run命令详解
go run专门用来运行命令源码文件的命令,不是用来运行所有go源码文件的
go run 命令只能接受一个命令源码文件以及若干个库源码文件(必须同属于 main 包)作为文件参数,且不能接受测试源码文件。它在执行时会检查源码文件的类型。如果参数中有多个或者没有命令源码文件,那么 go run 命令就只会打印错误提示信息并退出,而不会继续执行。
go run -n 查看执行过程
先创建临时文件b001,在b001中创建一个importcfg文件,将使用的import文件写入,然后切换到目录下,执行compile命令,创建一个importcfg.link文件,将compile生成的link写入。然后创建临时文件exe,将导入文件和源码文件连接在一起生成可执行文件。
通过compile生成link文件,然后将link和源文件一起打包成exe
生成的临时文件可以用go run -work看到
go run命令是生成了2个文件,一个是归档文件,一个是可执行文件。
$ go run -work main.go Trie.go
WORK=C:\Users\ADMINI~1\AppData\Local\Temp\go-build994767701
true, true
项目文件
文件go.mod
module gitcode.net/m
go 1.21.5
文件main.go
package main
import "fmt"
func main() {
obj := Constructor()
obj.Insert("apple")
param_2 := obj.Search("apple")
param_3 := obj.StartsWith("app")
fmt.Printf("%t, %t", param_2, param_3)
}
文件Trie.go
package main
type Trie struct {
children [26]*Trie
isEnd bool
}
func Constructor() Trie {
return Trie{}
}
func (t *Trie) Insert(word string) {
node := t
for _, ch := range word {
ch -= 'a'
if node.children[ch] == nil {
node.children[ch] = &Trie{}
}
node = node.children[ch]
}
node.isEnd = true
}
func (t *Trie) SearchPrefix(prefix string) *Trie {
node := t
for _, ch := range prefix {
ch -= 'a'
if node.children[ch] == nil {
return nil
}
node = node.children[ch]
}
return node
}
func (t *Trie) Search(word string) bool {
node := t.SearchPrefix(word)
return node != nil && node.isEnd
}
func (t *Trie) StartsWith(prefix string) bool {
return t.SearchPrefix(prefix) != nil
}
/**
* Your Trie object will be instantiated and called as such:
* obj := Constructor();
* obj.Insert(word);
* param_2 := obj.Search(word);
* param_3 := obj.StartsWith(prefix);
*/