Golang 解引用函数返回值

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

Golang derefencing function return value

问题

我正在使用flag库,并发现这段代码无法工作:

package main

import (
	"fmt"
	"flag"
)

var recursive bool

func init() {
	recursive = *flag.Bool("r", false, "Search recursively")
}
func main() {
	flag.Parse()

	fmt.Printf("Recursive: %t \n\n", recursive)

	flag.PrintDefaults()

}

但是下面这段代码可以工作(我已经注释了我修改的三行代码):

package main

import (
	"fmt"
	"flag"
)

var recursive *bool   // 改为指针类型

func init() {
	recursive = flag.Bool("r", false, "Search recursively") // 不再解引用函数
}
func main() {
	flag.Parse()

	fmt.Printf("Recursive: %t \n\n", *recursive)  // 解引用变量

	flag.PrintDefaults()

}

为什么会出现这种情况?在Go语言中,函数不允许解引用吗?还是我做错了其他事情?

英文:

I'm messing with the flag library, and found that this code does not work:

package main

import (
	"fmt"
	"flag"
)

var recursive bool

func init() {
	recursive = *flag.Bool("r", false, "Search recursively")
}
func main() {
	flag.Parse()

	fmt.Printf("Recursive: %t \n\n", recursive)

	flag.PrintDefaults()

}

But this does (I commented the three lines I changed):

package main

import (
	"fmt"
	"flag"
)

var recursive *bool   //Changed to pointer type

func init() {
	recursive = flag.Bool("r", false, "Search recursively") //Changed to not dereference function
}
func main() {
	flag.Parse()

	fmt.Printf("Recursive: %t \n\n", *recursive)  //Changed to dereference variable

	flag.PrintDefaults()

}

Why does this behave like this? Are functions not allowed to be dereferenced in Golang, or am I doing something else wrong?

答案1

得分: 2

这是因为当你调用flag.Bool()时,它还没有解析命令行参数,它只是定义了一个命名的标志,并用默认值进行初始化(根据你指定的,这个默认值是false)。

只有当你调用flag.Parse()时,命令行参数才会被解析。如果你在init()函数中使用recursive bool,默认的false值将被赋给它。flag包不知道你的recursive变量,所以当你稍后调用flag.Parse()时,它的值将不会被改变。

flag.Bool()返回一个指向bool变量的指针,flag包知道这个指针,当你调用flag.Parse()时,指向的bool变量将被正确更新,所以当你在flag.Bool()之后打印指向的值时,它将是根据你的命令行参数设置的更新值。

替代方法:注册你的变量

所以你必须存储并使用flag.Bool()返回的指针,否则你只会看到默认值。或者你可以让flag包知道你的recursive变量:你可以使用flag.BoolVar()函数告诉flag包将结果存储到_你的_recursive变量中:

flag.BoolVar(&recursive, "r", false, "递归搜索")

注意,在这种情况下,没有返回值,因为你明确提供了一个指向bool的指针,你希望flag包将结果存储到这个指针指向的变量中。

英文:

The reason for this is because when you call flag.Bool(), it does not yet parse the command line arguments, it just defines a named flag and initializes it with the default value (which is false as you specified it).

Command line arguments are only parsed when you call flag.Parse(). If you use recursive bool, in the init() function the default false will be assigned to it. The flag package does not know about your recursive variable, so later when you call flag.Parse(), its value will not/ cannot be changed.

flag.Bool() returns a pointer to a bool variable which the flag package knows about, and later when you call flag.Parse() the pointed bool variable will be properly updated, so when you print the pointed valued after flag.Bool(), it will be the updated value which will be set based on your command line arguments.

Alternative: Register your variable

So you must store and use the pointer returned by flag.Bool() else you will only see the default value. Or you can let the flag package know about your recursive variable: you can tell the flag package that you what it to store the result into your recursive variable by telling this with the flag.BoolVar() function:

flag.BoolVar(&recursive, "r", false, "Search recursively")

Note that in this case there is no return value, becase you explicitly provided a pointer to a bool which you want the flag package to store the result to.

huangapple
  • 本文由 发表于 2015年1月13日 14:40:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/27916268.html
匿名

发表评论

匿名网友

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

确定