英文:
Default struct values
问题
在Go语言中,对于类型有默认值。以int类型为例,它的默认值是0。
我遇到一个问题,对我来说,int类型的0可能是一个有效的值,所以我需要检查它是由我设置的还是默认初始化的。有没有办法区分它们呢?
考虑以下代码...我需要能够区分testIntOne
和testIntTwo
,但它们看起来是一样的!
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论