我是Go的初学者 . 将一片int转换为一串字符串似乎很简单,只需几行:
nums := []int{1, 2, 3, 4} sNums := make([]string, len(nums)) for i, x := range nums { sNums[i] = strconv.Itoa(x) }
但是,我想知道是否有办法使用内置/标准库使用快速单行程,类似于Python中的以下内容:
sNums = map(str, nums)
看来你正在寻找一个对切片进行操作的 map 函数 . 这将需要泛型,并且从Go 1.11开始,尚未支持泛型 . 标准库也没有为这些类型的操作(map,filter,reduce等)提供内置函数 .
map
对于这个简单的用例,你已经拥有的就足够了 . 将其包裹在一个功能中,以满足您的需要 . 在Go支持泛型之前,您必须在每种类型的切片上进行手写操作 .
一些阅读链接:
Generics Proposal
Rob Pike's Filter Library
您想要的只需一行即可完成,但这些解决方案与您在问题中提出的简单循环相比(性能较差) . 所以这里有一些单行,但我可能永远不会用它们来实现你想要的,所以只需使用 for 循环,如果你必须多次这样做,创建一个辅助函数(将使用循环),并只需调用辅助函数 .
for
以下单行都 Build 在fmt.Sprint()函数上,它为 int 切片生成一个字符串表示,如下所示(不带引号):
int
"[e1 e2 e3...]"
其中 e1 , e2 ...是输入切片的元素 .
e1
e2
例如:
nums := []int{1, 2, -3, 4} s := fmt.Sprint(nums) fmt.Printf("%q", s)
将输出(在Go Playground上尝试):
"[1 2 -3 4]"
我们可以使用两个步骤"transform"这个单独的 string 值:
string
摆脱前导和尾随方括号
拆分(中断)空格上的剩余文本
我们已经完成了 .
第一步,我们有几个选项,例如strings.Replace(),strings.Replacer,strings.Trim() . 我们可以通过切割字符串来剪切它的第一个字符(例如 s[1:] ),然后只需要删除尾随的 ']' .
s[1:]
']'
第二步,我们有strings.Split() .
如果没有所有可能的组合,这里有3个单线示例将 int 切片转换为 string 切片:
nums := []int{1, 2, -3, 4} sNums := strings.Split(strings.Replace(fmt.Sprint(nums)[1:], "]", "", -1), " ") fmt.Printf("%q\n", sNums) sNums2 := strings.Split(strings.Trim(fmt.Sprint(nums), "[]"), " ") fmt.Printf("%q\n", sNums2) sNums3 := strings.Split(strings.TrimRight(fmt.Sprint(nums)[1:], "]"), " ") fmt.Printf("%q\n", sNums3)
以上输出(在Go Playground上试试):
["1" "2" "-3" "4"] ["1" "2" "-3" "4"] ["1" "2" "-3" "4"]
有一个边缘情况,上述解决方案都没有处理:如果输入是空切片,则输出将是包含空字符串的切片(当它应该是空切片时) . 原因是因为如果输入不包含空格分隔符(在这种情况下它是空字符串), strings.Split() 将返回输入(这将是空字符串) .
strings.Split()
要处理空输入切片边缘情况,我们可以使用strings.SplitN()函数而不是 strings.Split() ,将 len(nums) 作为我们想要的最大部件数传递 . 因此,如果输入切片为空,则输出切片也将为空:
len(nums)
nums := []int{} sNums := strings.SplitN(strings.Replace(fmt.Sprint(nums)[1:], "]", "", -1), " ", len(nums)) fmt.Printf("%q\n", sNums) sNums2 := strings.SplitN(strings.Trim(fmt.Sprint(nums), "[]"), " ", len(nums)) fmt.Printf("%q\n", sNums2) sNums3 := strings.SplitN(strings.TrimRight(fmt.Sprint(nums)[1:], "]"), " ", len(nums)) fmt.Printf("%q\n", sNums3)
这将正确输出(在Go Playground上尝试):
[] [] []
这里需要注意的一点是:所提出的解决方案有点像通用解决方案,因为解决方案适用于其他类型的切片,例如: []int8 , []int32 , []float32 等,即使是数组,例如 [4]int ......
[]int8
[]int32
[]float32
[4]int
2 回答
看来你正在寻找一个对切片进行操作的
map
函数 . 这将需要泛型,并且从Go 1.11开始,尚未支持泛型 . 标准库也没有为这些类型的操作(map,filter,reduce等)提供内置函数 .对于这个简单的用例,你已经拥有的就足够了 . 将其包裹在一个功能中,以满足您的需要 . 在Go支持泛型之前,您必须在每种类型的切片上进行手写操作 .
一些阅读链接:
Generics Proposal
Rob Pike's Filter Library
您想要的只需一行即可完成,但这些解决方案与您在问题中提出的简单循环相比(性能较差) . 所以这里有一些单行,但我可能永远不会用它们来实现你想要的,所以只需使用
for
循环,如果你必须多次这样做,创建一个辅助函数(将使用循环),并只需调用辅助函数 .以下单行都 Build 在fmt.Sprint()函数上,它为
int
切片生成一个字符串表示,如下所示(不带引号):其中
e1
,e2
...是输入切片的元素 .例如:
将输出(在Go Playground上尝试):
我们可以使用两个步骤"transform"这个单独的
string
值:摆脱前导和尾随方括号
拆分(中断)空格上的剩余文本
我们已经完成了 .
第一步,我们有几个选项,例如strings.Replace(),strings.Replacer,strings.Trim() . 我们可以通过切割字符串来剪切它的第一个字符(例如
s[1:]
),然后只需要删除尾随的']'
.第二步,我们有strings.Split() .
如果没有所有可能的组合,这里有3个单线示例将
int
切片转换为string
切片:以上输出(在Go Playground上试试):
有一个边缘情况,上述解决方案都没有处理:如果输入是空切片,则输出将是包含空字符串的切片(当它应该是空切片时) . 原因是因为如果输入不包含空格分隔符(在这种情况下它是空字符串),
strings.Split()
将返回输入(这将是空字符串) .要处理空输入切片边缘情况,我们可以使用strings.SplitN()函数而不是
strings.Split()
,将len(nums)
作为我们想要的最大部件数传递 . 因此,如果输入切片为空,则输出切片也将为空:这将正确输出(在Go Playground上尝试):
这里需要注意的一点是:所提出的解决方案有点像通用解决方案,因为解决方案适用于其他类型的切片,例如:
[]int8
,[]int32
,[]float32
等,即使是数组,例如[4]int
......