英文:
Go type inference and named return variables
问题
在Go语言中,如果你给返回变量命名,它们在函数开始时会被初始化为它们的零值。我在下面的代码中使用了这个特性,其中在usr, err = user.Current()
这一行中给err
变量命名。是否可能对usr
变量使用类型推断,而不对err
变量使用类型推断?我真的不想声明var usr *user.user
,我更愿意在这里使用类型推断。
func getConfigFilepath(userSuppliedFilepath string) (filepath string, err error) {
if userSuppliedFilepath == "" {
usr, err = user.Current()
filepath = path.Join(usr.HomeDir, ".myprogram.config.json")
}
return
}
英文:
In Go if you give a name to the return variables they are initialised to their zero values when the function begins. I'm using this feature below with the err
variable on the line usr, err = user.Current()
. Is it possible to use type inference for usr
variable and not for the err
variable? I don't really want to declare var usr *user.user
I would much rather use type inference here.
func getConfigFilepath(userSuppliedFilepath string) (filepath string, err error) {
if userSuppliedFilepath == "" {
usr, err = user.Current()
filepath = path.Join(usr.HomeDir, ".myprogram.config.json")
}
return
}
答案1
得分: 4
不,你不能做你想做的事情。
你的选择是不使用命名返回值,或者像你说的那样声明:
var usr *user.User
usr, err = user.Current()
在某些情况下,你可以这样做,但在你的情况下,你正在创建一个新的 err
,因为你在 if 块内部,并且它正在创建一个局部作用域的新 err
引用。
英文:
No, you can't do what you want to do.
Your choices are to not use named returns, or like you said declare
var usr *user.User
usr, err = user.Current()
In some circumstances you could do that, but in your case you are are creating a new err
because you are within the if block and it is making a locally scoped reference to a new err
.
答案2
得分: 1
你可以稍微重构一下代码,不要将user.Current()
调用放在另一个块中(在你的情况下是if
),然后你可以使用:=
(短变量声明)来实现:
func getConfigFilepath(userSuppliedFilepath string) (filepath string, err error) {
if userSuppliedFilepath != "" {
return userSuppliedFilepath, nil
}
usr, err := user.Current()
filepath = path.Join(usr.HomeDir, ".myprogram.config.json")
return
}
编辑:
你可能会说这段代码比你原来的代码长,但请注意,你原来的代码尚不完整,也不合法,因为它没有处理userSuppliedFilepath
被提供的情况。你应该将提议的代码与下面的完整且合法的代码进行比较:
func getConfigFilepath(userSuppliedFilepath string) (filepath string, err error) {
if userSuppliedFilepath == "" {
var usr *user.User
usr, err = user.Current()
filepath = path.Join(usr.HomeDir, ".myprogram.config.json")
} else {
filepath = userSuppliedFilepath
}
return
}
现在,提议的代码并不比原来的代码长(相反,它稍微更短一些)。
英文:
You can if you slightly restructure your code and you don't put the user.Current()
call in another block (if
in your case), then you can do it with the :=
Short variable declaration:
func getConfigFilepath(userSuppliedFilepath string) (filepath string, err error) {
if userSuppliedFilepath != "" {
return userSuppliedFilepath, nil
}
usr, err := user.Current()
filepath = path.Join(usr.HomeDir, ".myprogram.config.json")
return
}
Edit:
You might say this code is longer than your original, but note that your original code is not yet valid and is also incomplete because it does not handle the case when userSuppliedFilepath
is provided. You should compare the proposed code to the full and valid version of your code which is below:
func getConfigFilepath(userSuppliedFilepath string) (filepath string, err error) {
if userSuppliedFilepath == "" {
var usr *user.User
usr, err = user.Current()
filepath = path.Join(usr.HomeDir, ".myprogram.config.json")
} else {
filepath = userSuppliedFilepath
}
return
}
And now the proposed code isn't longer (on the contrary, it's a little shorter).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论