默认结构值

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

Default struct values

问题

在Go语言中,对于类型有默认值。以int类型为例,它的默认值是0。

我遇到一个问题,对我来说,int类型的0可能是一个有效的值,所以我需要检查它是由我设置的还是默认初始化的。有没有办法区分它们呢?

考虑以下代码...我需要能够区分testIntOnetestIntTwo,但它们看起来是一样的!

package main

import "log"

type test struct {
    testIntOne int
    testIntTwo int
}

func main() {
    s := test{testIntOne: 0}

    log.Println(s)
}
英文:

In Go I get that there are default values for types. Take int in this case which is initialised as a 0.

I have an issue where for me a 0 in an int can be a valid value so I need to check if it's been set by me or initialised as such. Is there any way to tell the difference between them at all?

Considering the following code... I need to be able to tell the difference between testIntOne and testIntTwo but they look the same!

package main

import "log"

type test struct {
	testIntOne int
	testIntTwo int
}

func main() {
	s := test{testIntOne: 0}

	log.Println(s)
}

答案1

得分: 6

你无法区分它们,无法追踪一个字段(或变量)是否已经设置。

使用指针

你可以使用一个具有nil零值的指针,这样如果没有设置,你就可以知道:

type test struct {
    testIntOne *int
    testIntTwo *int
}

func main() {
    s := test{testIntOne: new(int)}

    fmt.Println("testIntOne set:", s.testIntOne != nil)
    fmt.Println("testIntTwo set:", s.testIntTwo != nil)
}

输出结果(在Go Playground上尝试):

testIntOne set: true
testIntTwo set: false

当然,new()只能用于获取一个指向int值为0的指针。查看这个问题以获取更多选项:https://stackoverflow.com/questions/30716354/how-do-i-do-a-literal-int64-in-go/30716481#30716481

使用方法

你还可以使用方法来设置一个字段,这样可以额外跟踪“isSet”属性。在这种情况下,你必须始终使用提供的方法来设置字段。最好将字段设为非导出的,这样其他人(包外)就无法直接访问它们。

type test struct {
    testIntOne int
    testIntTwo int

    oneSet, twoSet bool
}

func (t *test) SetOne(i int) {
    t.testIntOne, t.oneSet = i, true
}

func (t *test) SetTwo(i int) {
    t.testIntTwo, t.twoSet = i, true
}

func main() {
    s := test{}
    s.SetOne(0)

    fmt.Println("testIntOne set:", s.oneSet)
    fmt.Println("testIntTwo set:", s.twoSet)
}

输出结果(在Go Playground上尝试):

testIntOne set: true
testIntTwo set: false
英文:

You can't tell the difference, it is not tracked whether a field (or a variable) has been set or not.

Using a pointer

You may use a pointer which has a nil zero value, so if not set, you can tell:

type test struct {
	testIntOne *int
	testIntTwo *int
}

func main() {
	s := test{testIntOne: new(int)}

	fmt.Println("testIntOne set:", s.testIntOne != nil)
	fmt.Println("testIntTwo set:", s.testIntTwo != nil)
}

Output (try it on the Go Playground):

testIntOne set: true
testIntTwo set: false

Of course new() can only be used to obtain a pointer to an int value being 0. See this question for more options: https://stackoverflow.com/questions/30716354/how-do-i-do-a-literal-int64-in-go/30716481#30716481

Using a method

You may also use a method to set a field, which could take care of additionally tracking the "isSet" property. In this case you must always use the provided method to set the field. Best is to make fields unexported, so others (outside your package) won't have direct access to them.

type test struct {
	testIntOne int
	testIntTwo int

	oneSet, twoSet bool
}

func (t *test) SetOne(i int) {
	t.testIntOne, t.oneSet = i, true
}

func (t *test) SetTwo(i int) {
	t.testIntTwo, t.twoSet = i, true
}

func main() {
	s := test{}
	s.SetOne(0)

	fmt.Println("testIntOne set:", s.oneSet)
	fmt.Println("testIntTwo set:", s.twoSet)
}

Output (try it on the Go Playground):

testIntOne set: true
testIntTwo set: false

huangapple
  • 本文由 发表于 2016年12月5日 16:56:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/40970422.html
匿名

发表评论

匿名网友

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

确定