英文:
Better way to deal with arguments in my golang variadic function
问题
如果在下面的可变参数函数中只有一个参数,有没有更简洁的方法来将ip2
初始化为空字符串?
func myvariadic(ip ...string) {
ip1 := ip[0]
if len(ip) > 1 {
ip2 := ip[1]
} else {
ip2 := ""
///...
}
}
可以使用短变量声明和条件表达式来简化代码:
func myvariadic(ip ...string) {
ip1 := ip[0]
ip2 := ""
if len(ip) > 1 {
ip2 = ip[1]
}
///...
}
这样,无论是否有第二个参数,ip2
都会被初始化为空字符串。
英文:
Is there a shorter way to initialize ip2
to empty string if there is only one argument in my variadic function below?
func myvariadic(ip ...string) {
ip1 := ip[0]
if len(ip) > 1 {
ip2 := ip[1]
} else {
ip2 := ""
///...
}
答案1
得分: 3
你可以简单地使用以下代码:
func myvariadic(ip ...string) {
ip1, ip2 := ip[0], ""
if len(ip) > 1 {
ip2 = ip[1]
}
fmt.Println(ip1, ip2)
}
但是不要忘记,可变参数函数可以在指定/传递可变参数的值时不传递任何参数。这意味着,即使使用零参数调用myvariadic()
也是合法的(不会在编译时出错),然后甚至ip[0]
也会导致运行时错误。
如果你的函数必须至少接收一个字符串,并可选地接收第二个字符串,你应该将函数的签名更改为:
func myvariadic(ip1 string, ips ...string) {
ip2 := ""
if len(ips) > 1 {
ip2 = ips[1]
}
fmt.Println(ip1, ip2)
}
这样可以确保至少传递一个string
(否则将会在编译时出错)。如果只传递一个参数,这也更高效,因为不需要分配切片(ips
将使用nil
)。在这里可以了解更多详细信息:https://stackoverflow.com/questions/37270743/is-it-possible-to-trigger-compile-time-error-with-custom-library-in-golang/37271129#37271129
如果参数始终是1个或2个string
值,我不确定是否有必要使用可变参数,你可以简单地使用:
func myNonVariadic(ip1, ip2 string) {
fmt.Println(ip1, ip2)
}
如果ip2
不可用,只需在调用者处传递空字符串""
即可。
如果你仍然想坚持使用可变参数函数,另一个选项是在函数内部不引入ip1
和ip2
,而是直接使用ip[0]
和ip[1]
。为了避免在传递少于2个参数时发生运行时错误,你可以自己追加一个空字符串,例如:
func myvariadic(ip ...string) {
if len(ip) < 2 {
ip = append(ip, "")
}
fmt.Println(ip[0], ip[1])
}
处理0个参数的版本如下:
func myvariadic(ip ...string) {
for len(ip) < 2 {
ip = append(ip, "")
}
fmt.Println(ip[0], ip[1])
}
后一种版本确保切片类型的ip
变量至少有2个元素,即使传递了0个参数也是如此。
英文:
You may simply use:
func myvariadic(ip ...string) {
ip1, ip2 := ip[0], ""
if len(ip) > 1 {
ip2 = ip[1]
}
fmt.Println(ip1, ip2)
}
But don't forget that variadic functions may be called with 0 arguments specified / passed as the value for the variadic parameter. What this means is that it is also legal (not a compile-time error) to call myvariadic()
with zero arguments, and then even ip[0]
will cause a runtime panic.
If your function must receive at least one string and optionally a second, you should change the signature of your function to this:
func myvariadic(ip1 string, ips ...string) {
ip2 := ""
if len(ips) > 1 {
ip2 = ips[1]
}
fmt.Println(ip1, ip2)
}
What this guarantees is that 1 string
will surely be passed (else it would be a compile-time error). This is also more efficient if only one argument is passed, as no slice allocation will be needed (nil
will be used for ips
). See more details on this here: https://stackoverflow.com/questions/37270743/is-it-possible-to-trigger-compile-time-error-with-custom-library-in-golang/37271129#37271129
If parameters are always 1 or 2 string
values, I'm not sure variadic parameters is justified at all, you may simply use:
func myNonVariadic(ip1, ip2 string) {
fmt.Println(ip1, ip2)
}
And simply pass the empty string ""
at the caller if ip2
is not available.
If you still want to stick to variadic function, another option would be to not introduce ip1
and ip2
inside the function, but simply use ip[0]
and ip[1]
. And to avoid runtime panic if less than 2 arguments is passed, you may append an empty string yourself, e.g.:
func myvariadic(ip ...string) {
if len(ip) < 2 {
ip = append(ip, "")
}
fmt.Println(ip[0], ip[1])
}
And the version that also deals with 0 arguments:
func myvariadic(ip ...string) {
for len(ip) < 2 {
ip = append(ip, "")
}
fmt.Println(ip[0], ip[1])
}
This latter version makes sure the ip
variable (of slice type) will have at least 2 elements, even if 0 is passed.
答案2
得分: 2
声明所有的局部变量并移除else
。这是我能想到的另一种方式:
func myvariadic(ip ...string) {
ip1 := ip[0]
var ip2 string
if len(ip) > 1 {
ip2 = ip[1]
}
fmt.Println(ip1, ip2)
}
请注意,这只是代码的翻译,没有其他额外的内容。
英文:
Declare all locals up front and remove else
. This is the only other way I could think of:
func myvariadic(ip ...string) {
ip1 := ip[0]
var ip2 string
if len(ip) > 1 {
ip2 = ip[1]
}
fmt.Println(ip1,ip2)
答案3
得分: 1
你根本不需要进行初始化。在Go语言中,所有的基本类型都会被初始化为它们的默认值。
也就是说,下面的表达式是成立的。
a := ""
var b string
fmt.Println(a == b)
因此,你推断的ip2 := ""
已经是你可以输入的最简洁版本了。
英文:
You don't need to initialize at all. All primitive types are initialized to their default values in Go.
IOW, this is true.
a := ""
var b string
fmt.Println(a == b)
https://play.golang.org/p/hwQmU4Myrp
Therefore, you inferred assignment of ip2 := ""
is already the most succinct version you can type.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论