Golang中暴露只读变量的常见规范是什么

Golang中暴露只读变量的常见规范是什么 我是Go语言的新手,所以请原谅我的无知。我来自C#/Java背景,那里有公共/私有属性(或getter/setter)。然而,在Go中,这种方法并不存在。变量要么以大写字母开头,因此是公共的;要么以小写字母开头,因此是私有的。例如,在C#中,我们可以有公共get但私有set的属性。

在包中暴露公共变量的常见规范是什么,这些变量不应被包外的任何代码修改?

2 回复

你好。我认为,如果它应该是只读的,在这种情况下,你需要将其设为非导出,并添加一个导出的获取方法,例如:

type Test struct {
    readOnly string
}

func (t *Test) GetReadOnly() string { return t.readOnly }

这样,你将能够在包内使用这个变量,同时防止用户直接访问它,但又能提供一个接口供外部读取其值。

在我看来,Go语言中的获取器/设置器是根据其自身的设计模式出现的。如果你想给予用户对内部变量的完全访问权限,那么直接将其导出即可。但是,举个例子,如果更新该变量会触发某些内部逻辑,那么最好将其设为非导出,并添加一个额外的设置方法,例如:

type Test struct {
    SimpleVar string
    specialVar string
}

func (t *Test) SetSpecial(str string) {
    // 在重新赋值前执行一些逻辑,例如:
    t.specialVar = t.SimpleVar + str
}

func (t *Test) GetSpecial() string { return t.specialVar }

更多关于Golang中暴露只读变量的常见规范是什么的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,暴露只读变量的常见规范有以下几种方法:

1. 通过函数暴露只读值

package mypackage

// 私有变量
var configValue string = "default"

// 公共只读访问函数
func GetConfigValue() string {
    return configValue
}

// 包内可以修改
func internalSetConfig(value string) {
    configValue = value
}

2. 使用常量(如果值不变)

package mypackage

// 公共常量 - 完全只读
const (
    MaxConnections = 100
    DefaultTimeout = 30 * time.Second
)

3. 返回副本而不是引用

package mypackage

type Config struct {
    Host string
    Port int
}

var defaultConfig = Config{
    Host: "localhost",
    Port: 8080,
}

// 返回结构体的副本
func DefaultConfig() Config {
    return defaultConfig
}

// 或者返回指针,但文档说明不应修改
func GetDefaultConfig() *Config {
    // 返回新实例的指针
    cfg := defaultConfig
    return &cfg
}

4. 使用接口限制访问

package mypackage

type ReadOnlyConfig interface {
    GetHost() string
    GetPort() int
}

type config struct {
    host string
    port int
}

func (c *config) GetHost() string {
    return c.host
}

func (c *config) GetPort() int {
    return c.port
}

var globalConfig = &config{
    host: "localhost",
    port: 8080,
}

func GetConfig() ReadOnlyConfig {
    return globalConfig
}

5. 对于切片和映射,返回副本

package mypackage

var allowedIPs = []string{"192.168.1.1", "10.0.0.1"}

func GetAllowedIPs() []string {
    // 返回切片的副本
    ips := make([]string, len(allowedIPs))
    copy(ips, allowedIPs)
    return ips
}

var settings = map[string]string{
    "mode": "production",
    "log":  "info",
}

func GetSettings() map[string]string {
    // 返回映射的副本
    copy := make(map[string]string)
    for k, v := range settings {
        copy[k] = v
    }
    return copy
}

6. 实际示例

package server

import "time"

// 私有配置
var serverConfig = struct {
    maxConnections int
    timeout        time.Duration
    allowedOrigins []string
}{
    maxConnections: 100,
    timeout:        30 * time.Second,
    allowedOrigins: []string{"example.com", "api.example.com"},
}

// 只读访问器
func MaxConnections() int {
    return serverConfig.maxConnections
}

func Timeout() time.Duration {
    return serverConfig.timeout
}

func AllowedOrigins() []string {
    origins := make([]string, len(serverConfig.allowedOrigins))
    copy(origins, serverConfig.allowedOrigins)
    return origins
}

// 包内初始化函数
func initConfig(maxConn int, timeout time.Duration) {
    serverConfig.maxConnections = maxConn
    serverConfig.timeout = timeout
}

Go社区通常偏好使用函数(getter)而不是直接暴露变量,即使变量本身不会改变。这种方式提供了更好的封装和未来修改的灵活性。对于简单的常量值,直接使用公共常量是最直接的方法。

回到顶部