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

5 回复

已按要求完成

更多关于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包中无法访问。以下是修复步骤:

  1. svr包中,将Link变量改为首字母大写(例如Link -> Link),以导出它。
  2. 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应该不再报错。如果问题仍然存在,检查模块设置和导入路径。

回到顶部