Golang中如何创建重复的包级变量

Golang中如何创建重复的包级变量 我在Goland中创建同名包级变量时收到警告 - 我在同一个目录下创建了多个Go文件,每个文件都有一个同名变量 - 但它仍然可以成功运行。那么,Go语言是否允许在同一个目录下的不同文件中使用同名变量?我认为这绝对不是好的做法,但想知道实际后果是什么。

谢谢

5 回复

你能稍微解释一下吗,不太明白你的意思。

更多关于Golang中如何创建重复的包级变量的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


main 包有所不同。该包中的不同文件是相互独立的。

我无法复现这个问题,我遇到了构建错误:

$ for f in $(\ls *.go); do printf "# File: %s\n" $f; cat $f; done
# File: bar.go
package duplicate

var foo int
# File: foo.go
package duplicate

var foo int
$ go build
# _/tmp/tmp.jpv0KFpdQj
./foo.go:3:5: foo redeclared in this block
	previous declaration at ./bar.go:3:5
$ echo $?
2

那么你是如何构建的?文件的内容是什么?

同一目录下有两个文件,仍然可以运行和构建

package main

import (
	"fmt"
	"runtime"
	_ "runtime"
	"sync"
)

var (
	counter int
	wg sync.WaitGroup
)

func main(){
	wg.Add(2)

	go incCounter(1)
	go incCounter(2)

	wg.Wait()
	fmt.Println("final counter: ", counter)
}

func incCounter(input int){
	defer wg.Done()
	for count := 0; count < 2; count++{
		value := counter
		//do werld thing
		runtime.Gosched()
		value ++
		counter = value
	}
	fmt.Println("done by ", input)
}

第二个文件:

package main

import (
	"fmt"
	"runtime"
	"sync"
	"sync/atomic"
	_ "sync/atomic"
)

var (
	counter int32
	wg sync.WaitGroup
)
func main(){
	fmt.Println(runtime.GOMAXPROCS(0))
	fmt.Println(runtime.NumCPU())
	//runtime.GOMAXPROCS(1)
	//fmt.Println(runtime.GOMAXPROCS(0))
	wg.Add(2)

	go incCounter(1)
	go incCounter(2)

	wg.Wait()
	fmt.Println("final counter: ", counter)
	fmt.Println(runtime.GOMAXPROCS(0))
}

func incCounter(input int){
	defer wg.Done()
	//value := counter
	atomic.AddInt32(&counter, 1)
	atomic.AddInt32(&counter, 1)
	//counter++
	//counter++
}

在Go语言中,同一个包(即同一个目录下)的不同文件中不允许定义同名的包级变量,因为这会导致编译错误。Go编译器会报错"重复定义"(redeclared),而不是仅仅警告。如果你在Goland中看到的是警告而非错误,并且程序能运行,可能是因为这些变量实际上被定义在了不同的包中,或者你使用了某些构建标签(build tags)条件编译,导致它们在编译时被区分开。

在标准情况下,如果你在同一个包的多个文件中定义同名包级变量,编译器会报错。例如:

文件 a.go

package main

var globalVar int = 10

文件 b.go

package main

var globalVar int = 20 // 编译错误:globalVar redeclared in this block

这会导致编译失败,错误信息指出变量在同一块中重复声明。Go语言要求包级标识符(变量、函数、类型等)在包内唯一。

如果程序成功运行,可能的原因包括:

  1. 这些文件属于不同的包(即 package 声明不同),因此变量在不同包中,不冲突。
  2. 使用了构建约束,例如在文件头添加 // +build tag,使得某些文件在特定条件下编译,避免同时包含同名变量。
  3. 变量定义在函数内部(局部变量),而不是包级。

实际后果是:如果确实在同一个包中重复定义包级变量,编译器会阻止构建,程序无法运行。因此,确保包级变量名称在包内唯一是必要的。如果遇到警告但能运行,请检查文件所属的包和构建配置。

回到顶部