在Go语言中,将一个字符串类型的数组转换为另一个字符串类型的数组,最佳方法是什么?

4
以下是代码:
package main

import "strings"
import "fmt"

type Foo string

const (
    Bar    Foo = "bar"
    Snafu      = "snafu"
    Foobar     = "foobar"
)

var Foos = []Foo{Bar, Snafu, Foobar}

func main() {
    fmt.Println("Foos: " + strings.Join(Foos, ","))
}

产生如下错误:
./test.go:17: cannot use Foos (type []Foo) as type []string in argument to strings.Join

这很有道理,因为Foo不是字符串,而是从字符串派生出来的。有没有办法在不复制的情况下强制将"[]Foo"转换为"[]string"?
2个回答

5

最好的方法也是唯一的方法,就是通过循环遍历Foo对象的切片(会导致复制):

func main() {
    results := make([]string, 0, len(Foos))
    for _, r := range Foos{
       results = append(results, string(r))
    }
    fmt.Println("Foos: " + strings.Join(results, ","))
}

很遗憾,截至目前Go不支持类型强制转换的概念,需要进行复制。作为替代方案,您可以为[]Foo类型定义一个字符串方法,并将其作为类型别名,从而封装这些细节,例如:http://play.golang.org/p/FuOoLNrCvD 请参阅以下类似问题:无法将[]string转换为[]interface {}

1
结果应该是:results := make([]string, len(Foos)),而不是 results := make([]string, 0) - OneOfOne
1
@OneOfOne 我也曾这样想过,但实际上使用“results:= make([]string,len(Foos))”会引入一个错误。这是因为此初始化将创建一个充满nil的数组。然后您将附加到此数组。因此,您在开头得到“k x nil”单元格,然后是结果。我可以理解您的观点-我们需要更改for循环内部的代码,如下所示:“results [i] = string(r)”<-这将用每个单元格的正确值替换nils。 - XDS
@XDS results := make([]string, 0, len(Foos)),已更新答案。 - OneOfOne

0

你可以使用我创建的https://github.com/ledongthuc/goterators#map来重用聚合和转换函数。

enter image description here

package main

import (
    "fmt"
    "strings"

    "github.com/ledongthuc/goterators"
)

type Foo string

const (
    Bar    Foo = "bar"
    Snafu      = "snafu"
    Foobar     = "foobar"
)

var Foos = []Foo{Bar, Snafu, Foobar}

func main() {
    strs := goterators.Map(Foos, func(item Foo) string {
        return string(item)
    })
    fmt.Println("Foos: " + strings.Join(strs, ","))
}

或者如果你想要一种优化的方式,你可以使用Reduce函数

enter image description here

package main

import (
    "fmt"

    "github.com/ledongthuc/goterators"
)

type Foo string

const (
    Bar    Foo = "bar"
    Snafu      = "snafu"
    Foobar     = "foobar"
)

var Foos = []Foo{Bar, Snafu, Foobar}

func main() {
    joinStr := goterators.Reduce(Foos, "", func(previous string, current Foo, index int, list []Foo) string {
        if len(previous) == 0 {
            return string(current)
        }
        return previous + "," + string(current)
    })
    fmt.Println("Foos: " + joinStr)
}

他们需要使用 Go 1.18 版本才能使用支持泛型和动态类型的功能。


1
当链接到您自己的网站或内容(或与您有关联的内容)时,您必须在答案中披露您的关联,以便不被视为垃圾邮件。在用户名中具有与URL相同的文本或在个人资料中提及它不被视为足够的披露根据Stack Exchange政策。 - cigien
感谢您的回复。我会进行更新! - Le Dong Thuc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接