Is there an efficient way to initialize a fixed array in Go without polluting the package namespace?

huangapple go评论81阅读模式
英文:

Is there an efficient way to initialize a fixed array in Go without polluting the package namespace?

问题

这是一个存储syslog Facility值的类型的实现:

package main

import (
	"fmt"
)

// Facility - as defined in RFC 5424
type Facility uint8

var facilityName []string = []string{
	"kernel",
	"user",
	"...",
	"local7",
}

func (s Facility) String() string {
	if int(s) < len(facilityName) {
		return facilityName[s]
	} else {
		return fmt.Sprintf("facility(%d)!", int(s))
	}
}

func UnknownFacility() Facility {
	return Facility(1) // "user"
}

这种实现的问题在于它将facilityName放在了包的命名空间中。另一种选择是在String()函数内部创建这个数组或切片,但这样会在每次调用String()时创建一个新的切片/数组。生成的代码效率不高。

有没有一种高效的方法来实现这个,并且不会污染命名空间?

UnknownFacility()也感觉像是匈牙利命名法...

英文:

Here's an implementation of a type which stores a syslog Facility value:

package main

import (
	&quot;fmt&quot;
)

// Facility - as defined in RFC 5424
type Facility uint8

var facilityName []string = []string{
	&quot;kernel&quot;,
	&quot;user&quot;,
	&quot;...&quot;,
	&quot;local7&quot;,
}

func (s Facility) String() string {
	if int(s) &lt; len(facilityName) {
		return facilityName
展开收缩
} else { return fmt.Sprintf(&quot;facility(%d)!&quot;, int(s)) } } func UnknownFacility() Facility { return Facility(1) // &quot;user&quot; }

The problem with this is that it puts it puts facilityName in the package namespace. The alternative is to create this array or slice inside the String() function, but this creates a new slice/array on every call to String(). The generated code isn't efficient.

Is there a way of doing this efficiently and not polluting the namespace?

UnknownFacility() also feels like Hungarian Notation...

答案1

得分: 1

简短的回答似乎是否定的。

  1. Go编译器(1.18.2)不会优化在函数中创建“常量”数组/切片的过程,并且Go中没有类似于C/C++静态变量的概念。因此,这样的数组需要存储在包变量中,以避免在每次函数调用时重新创建它们的开销。(例如,参见https://godbolt.org/z/TGPE75Kdf的编译器输出)。
  2. 在包内部,没有机制可以将变量的可见性限制在有限数量的函数中。(Go缺乏类似于C++的匿名命名空间)

我正在通过给只需要文件范围的变量命名添加前缀*_filename*来解决这个问题,这样它们就不会发生冲突,并且在IDE的自动完成中很容易区分。

将只需要文件或函数范围的变量添加到内部包命名空间是否是一个重要问题是另一个问题。

英文:

The short answer seems to be No.

  1. The Go compiler (1.18.2) doesn't optimize creating a "constant" array / slice in a function, and there's no equivalent in Go of a C/C++ static variable. Such arrays therefore need to be stored in a package variable to avoid the overhead of recreating them on every function call. (See https://godbolt.org/z/TGPE75Kdf for example compiler output).
  2. There's no mechanism to limit the visibility of a variable to a limited number of functions inside a package. (Go lacks an equivalent to a C++ anonymous namespace)

I'm working around this with a naming convention of prefixing variable names which only need file scope with _filename so they can't collide and are easy to distinguish in IDE auto-completion.

Whether adding variable names which only need file or function scope to the internal package namespace is a significant concern is a different question.

huangapple
  • 本文由 发表于 2022年6月1日 06:01:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/72454524.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定