【问题标题】:Detecting uninitialized struct fields检测未初始化的结构字段
【发布时间】:2017-05-08 17:47:27
【问题描述】:

我有一个用 golang 编写的服务,可以使用一些选项进行初始化。选项作为结构传递给构造函数。构造函数使用未包含的选项字段的默认值。这是一个例子:

type Service struct {
  options Options
}

type Options struct {
  BoolOption bool
  StringOption string
}

const (
  DefaultBoolOption = true
  DefaultStringOption = "bar"
)

func New(opts Options) *Service {
  if !opts.BoolOption {
    opts.BoolOption = DefaultBoolOption
  }

  if len(opts.StringOption) < 1 {
    opts.StringOption = DefaultStringOption
  }

  return &Service{options: opts,}
}

...

// elsewhere in my code
o := Options{BoolOption: false,}

// sets s.options.BoolOption to true!!!
s := New(o)

我的问题是,对于boolint 选项类型,我无法判断选项结构中是否设置了字段值。例如,BoolOption 是设置为 false 还是未初始化?

一种可能的解决方案是对我的所有选项字段使用字符串。例如,BoolOption 将是 "false" 而不是 false。然后我可以检查字符串的长度以检查它是否已初始化。

有更好的解决方案吗?

【问题讨论】:

  • 如果您希望它是显式可选的(并且您关心未初始化与默认值),您可能希望使用*bool 而不是bool。但这会让事情变得更难处理,所以请确保你需要。
  • @OliviaRuth:是的,我认为这是我唯一真正的解决方案。但就像你说的,它让事情变得稍微复杂一些。也许有可选输入对我来说并不重要。
  • 值得注意的是,如果布尔值的默认值为“true”,您可能应该反转布尔值。例如,如果布尔值是“logInput”,并且您希望它默认为 on,您可能应该将布尔选项设置为“noLog”并默认为 false。这遵循了让默认值有用的 Go 公理。
  • 这里有两个选项,一个是使用字段指针,第二个是封装Options 结构并为记录/检查是否为的字段生成GetSet 方法设置。

标签: go


【解决方案1】:

对于检测未初始化的结构字段,通常某些类型具有零值,否则它们是nil(地图和通道需要成为maked):

var i int     // i = 0
var f float64 // f = 0
var b bool    // b = false
var s string  // s = ""
var m chan int// c = nil

有一张tour 幻灯片很有用。

我认为您的问题涉及创建 默认布尔值 true


但是,为了您的利益,如果您将 Option 结构传递给该函数,并且用户没有指定选项,那么 它们将是 false""默认。

一个解决方案是创建一个(另一个)构造函数:func NewOptions(b bool, s string) Options

此构造函数将使 bool 默认为 true

您也可以尝试使用枚举来模拟布尔值; 零值将为0。因此,对于 Options 结构值 BoolOption,您可以使用 int,而不是 type bool

const (
        TRUE
        FALSE
)

您也可以将UNINITIALIZED 设为零,但我认为您只想切换默认值,而不是检测到它未初始化。

所以当检查Options 的值时,你可以这样写:

if opt.BoolOption == FALSE {
    // Do something with the option
} else {
    // The default option
}

更简单一点的是将BoolOption 变成notBoolOption,并将默认设置为false。


或者,正如 Olivia Ruth 指出的那样,如果您将该字段作为指向布尔值的指针,则它将保持 nil 直到“初始化”。

【讨论】:

  • 谢谢。我认为唯一的其他选择,正如@Olivia Ruth 指出的那样,我可以在 options struct 内部使用指针并检查 nil。
【解决方案2】:

bool 的默认值为 false。如果您注意到每次运行代码时都将选项值覆盖为 true。

字符串变量的默认值为“”。因此,如果使用len(opts.StringOption) == 0opts.StringOption == "" 检查字符串也可以。

https://play.golang.org/p/jifZZvoBVZ

【讨论】:

    猜你喜欢
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多