Go类型推断和命名返回变量

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

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).

huangapple
  • 本文由 发表于 2015年2月4日 14:16:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/28314691.html
匿名

发表评论

匿名网友

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

确定