在分配时解压缩Golang切片?

Seb*_*tos 40 go

在Golang中有一种优雅的方式可以从像Python这样的数组中进行多项赋值吗?这是我正在尝试做的Python示例(拆分字符串然后将结果数组分配给两个变量).

python:
>>> a, b = "foo;bar".split(";")
Run Code Online (Sandbox Code Playgroud)

我目前的解决方案是:

x := strings.Split("foo;bar", ";")
a, b := x[0], x[1]
Run Code Online (Sandbox Code Playgroud)

我可以看到这在一些结构中变得混乱.我目前面临的一个实际例子是书签文件解析并分配给地图:

bookmark := make(map[string]string)
x := strings.Split("foo\thttps://bar", "\t")
name, link := x[0], x[1]
bookmark[name] = link
Run Code Online (Sandbox Code Playgroud)

现在我坐着一个无用的变量"x".我想做点什么:

bookmark := make(map[string]string)
name, line := strings.Split("foo\thttps://bar", "\t")
bookmark[name] = link
Run Code Online (Sandbox Code Playgroud)

但那是无效的.

val*_*val 42

正如Sergio Tulentsev所提到的,不支持使用Python完成的一般打包/解包.我认为去那里的方法是使用多个返回值定义自己的小型ad-hoc函数:

func splitLink(s, sep string) (string, string) {
    x := strings.Split(s, sep)
    return x[0], x[1]
}
Run Code Online (Sandbox Code Playgroud)

然后你可以写:

name, link := splitLink("foo\thttps://bar", "\t")
Run Code Online (Sandbox Code Playgroud)

但是,这显然只有在至少两个子串分裂时才会起作用,并且如果超过两个子串则默默地忽略.如果这是你经常使用的东西,它可能会使你的代码更具可读性.

- 编辑 -

解包数组的另一种方法是通过可变参数指针参数:

func unpack(s []string, vars... *string) {
    for i, str := range s {
        *vars[i] = str
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个让你写:

var name, link string
unpack(strings.Split("foo\thttps://bar", "\t"), &name, &link)
bookmarks[name] = link
Run Code Online (Sandbox Code Playgroud)

这适用于任何数组大小,但可读性较差,您必须明确声明变量.


ANi*_*sus 10

如果你的函数只是在第一次出现分隔符时拆分字符串,你可以随时创建自己的函数:

package main

import (
    "fmt"
    "strings"
)

func Split(s, sep string) (string, string) {
    // Empty string should just return empty
    if len(s) == 0 {
        return s, s
    }   

    slice := strings.SplitN(s, sep, 2)

    // Incase no separator was present
    if len(slice) == 1 {
        return slice[0], ""
    }

    return slice[0], slice[1]
}

func main() {
    a, b := Split("foo;bar;foo", ";")
    fmt.Println(a, b)
}
Run Code Online (Sandbox Code Playgroud)

输出:

foo bar; foo

操场

  • “你总是可以创建自己的功能” - Go 社区关于 Go 的每个可能缺失的功能。 (6认同)

Jam*_*rke 8

您还可以使用匿名函数:

a, b := func() (string, string) {
    x := strings.Split("foo;bar", ";")
    return x[0], x[1]
}()
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记()右括号末尾的 ,}否则会出现错误:

assignment mismatch: 2 variable but 1 values

这是因为没有()函数(1 个值)返回的不是预期的字符串(2 个值)。

  • 最好有:`x, y, z := ...array` (6认同)
  • 如果是像这样简单的东西,您将在代码库中一次性使用它,那就没问题了。不过,取决于项目的大小和风格,如果您已经有一个专用于临时功能的包,则不想开始删除它们 (2认同)