Golang中Module初始化代码引用未定义问题已解决
Golang中Module初始化代码引用未定义问题已解决 主包
package main
import ("fmt";"svr";"shutdown")
func main(){
fmt.Println("Inits ran OK");
}
src/svr/svr.go
package svr
import ("net";"os";"log";"fmt")
func init(){
Link,err:= net.Listen("unix","/tmp/XXXX");
if err!=nil{
log.Fatal("由于无法建立数据库连接而终止");
os.Exit(1);}
go func(){
for{
_,err:=Link.Accept();
if err!=nil{
log.Fatal("接受连接失败 ",err);}
fmt.Println("收到接受请求");
}
}();
}
src/shutdown/shutdown.go
package shutdown
import ("svr";"net";"os";"os/signal";"syscall")
func init(){
sigc:= make(chan os.Signal,1);
signal.Notify(sigc,os.Interrupt,syscall.SIGTERM)
go func(link net.Listener, c chan os.Signal){
sig:= <-c;
println("立即关闭");
link.Close();
os.Exit(0);
}(svr.Link,sigc);
println("关闭处理程序已初始化");
}
运行 go run test.go 时出现以下错误:
bjc@sol2 ~/go4 $ go run test.go
shutdown
src/shutdown/shutdown.go:13:5: 未定义:svr.Link
有哪位好心人能告诉我遗漏了什么吗?
提前感谢
更多关于Golang中Module初始化代码引用未定义问题已解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
提示:请使用编辑框上方的</>按钮标记代码片段。这样代码会更具可读性。
您也可以像这样发布代码:如何在此论坛上发布代码
问题是":="定义了一个局部变量,因此Link没有被外部化。
修正后的svr.go
package svr
import ("net";"os";"log";"fmt")
var Link net.Listener;
var err error;
func init(){
Link,err= net.Listen("unix","/tmp/XXXX");
if err!=nil{
log.Fatal("Terminating as unable to setup Database link");
os.Exit(1);}
go func(){
for{
_,err:=Link.Accept();
if err!=nil{
log.Fatal("Accept failed ",err);}
fmt.Println("Accept rcvd");
}
}();
在Go语言中,包级别的变量(如svr.Link)需要首字母大写才能从其他包中访问。这是因为Go的可见性规则基于标识符的首字母大小写:首字母大写的标识符是导出的(公开的),而首字母小写的标识符是未导出的(私有的)。
在你的代码中,svr包中的Link变量是小写的,因此在shutdown包中无法访问。以下是修复步骤:
- 在
svr包中,将Link变量改为首字母大写(例如Link->Link),以导出它。 - 在
shutdown包中,通过svr.Link引用它。
修改后的代码示例:
src/svr/svr.go:
package svr
import (
"fmt"
"log"
"net"
"os"
)
var Link net.Listener // 将变量名改为大写以导出
func init() {
var err error
Link, err = net.Listen("unix", "/tmp/XXXX")
if err != nil {
log.Fatal("由于无法建立数据库连接而终止")
os.Exit(1)
}
go func() {
for {
_, err := Link.Accept()
if err != nil {
log.Fatal("接受连接失败 ", err)
}
fmt.Println("收到接受请求")
}
}()
}
src/shutdown/shutdown.go:
package shutdown
import (
"net"
"os"
"os/signal"
"svr"
"syscall"
)
func init() {
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, os.Interrupt, syscall.SIGTERM)
go func(link net.Listener, c chan os.Signal) {
sig := <-c
println("立即关闭")
link.Close()
os.Exit(0)
}(svr.Link, sigc) // 现在可以正确访问svr.Link
println("关闭处理程序已初始化")
}
**主包(test.go)**保持不变:
package main
import (
"fmt"
"shutdown"
"svr"
)
func main() {
fmt.Println("Inits ran OK")
}
确保你的模块配置正确(例如,使用go.mod文件),并且所有包在模块路径中可访问。运行go run test.go应该不再报错。如果问题仍然存在,检查模块设置和导入路径。

