英文:
Golang - mapping an variable length array to a struct
问题
我有一个如下的结构体:
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
我有一个由斜杠分隔的字符串,我想将其映射到这个结构体:
part1/part2/part3
然而,该字符串可能只包含一个部分,例如part1,或者包含两个部分,例如part1/part2
如果任何部分缺失,它必须映射为空字符串。
我对Go语言非常陌生,想知道实现这个的最佳方法是什么。通常我会分割字符串并检查长度来确定该做什么。在Go中是否有更优雅的方法来实现这个?
英文:
I have a struct as follows:
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
I have a string separated by slashes that I want to map to this:
part1/part2/part3
However, the string may only contain 1 part such as part1 or two parts such as part1/part2
if any part is missing it much be mapped as an empty string.
I am very new to go so wondering what the best way to achieve this is. Typically i would split the string and check the length to know what to do. In go is there a more elegant way to do this?
答案1
得分: 4
这是peterSO解决方案的一个版本,它使用一个包装器来简化逻辑。
package main
import (
"fmt"
"strings"
)
type Wrap []string
func (w Wrap) Get(i int) string {
if 0 <= i && i < len(w) {
return w[i]
}
return ""
}
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
func main() {
str := "part1/part2/part3"
split := Wrap(strings.Split(str, "/"))
var parts MyStruct
parts.Part1 = split.Get(0)
parts.Part2 = split.Get(1)
parts.Part3 = split.Get(2)
fmt.Println(parts)
str = "part1/part2"
split = Wrap(strings.Split(str, "/"))
parts = MyStruct{}
parts.Part1 = split.Get(0)
parts.Part2 = split.Get(1)
parts.Part3 = split.Get(2)
fmt.Println(parts)
}
英文:
Here's a version of peterSO's solution that uses a wrapper to help simplify the logic.
package main
import (
"fmt"
"strings"
)
type Wrap []string
func (w Wrap) Get(i int) string {
if 0 <= i && i < len(w) {
return w[i]
}
return ""
}
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
func main() {
str := "part1/part2/part3"
split := Wrap(strings.Split(str, "/"))
var parts MyStruct
parts.Part1 = split.Get(0)
parts.Part2 = split.Get(1)
parts.Part3 = split.Get(2)
fmt.Println(parts)
str = "part1/part2"
split = Wrap(strings.Split(str, "/"))
parts = MyStruct{}
parts.Part1 = split.Get(0)
parts.Part2 = split.Get(1)
parts.Part3 = split.Get(2)
fmt.Println(parts)
}
答案2
得分: 4
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
func (m *MyStruct) set(s string) *MyStruct {
p := []*string{&m.Part1, &m.Part2, &m.Part3}
for i, v := range strings.Split(s+"//", "/")[:3] {
*p[i] = v
}
return m
}
func main() {
var v MyStruct
fmt.Printf("%#v\n", v.set("foo"))
fmt.Printf("%#v\n", v.set(""))
fmt.Printf("%#v\n", v.set("bar/baz"))
fmt.Printf("%#v\n", v.set("alpha//omega"))
fmt.Printf("%#v\n", v.set("/var/mail"))
}
英文:
package main
import (
"fmt"
"strings"
)
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
func (m *MyStruct) set(s string) *MyStruct {
p := []*string{&m.Part1, &m.Part2, &m.Part3}
for i, v := range strings.Split(s+"//", "/")[:3] {
*p[i] = v
}
return m
}
func main() {
var v MyStruct
fmt.Printf("%#v\n", v.set("foo"))
fmt.Printf("%#v\n", v.set(""))
fmt.Printf("%#v\n", v.set("bar/baz"))
fmt.Printf("%#v\n", v.set("alpha//omega"))
fmt.Printf("%#v\n", v.set("/var/mail"))
}
Output:
&main.MyStruct{Part1:"foo", Part2:"", Part3:""}
&main.MyStruct{Part1:"", Part2:"", Part3:""}
&main.MyStruct{Part1:"bar", Part2:"baz", Part3:""}
&main.MyStruct{Part1:"alpha", Part2:"", Part3:"omega"}
&main.MyStruct{Part1:"", Part2:"var", Part3:"mail"}
答案3
得分: 1
例如,
package main
import (
"fmt"
"strings"
)
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
func main() {
str := "part1/part2/part3"
split := strings.Split(str, "/")
var parts MyStruct
if len(split) > 0 {
parts.Part1 = split[0]
if len(split) > 1 {
parts.Part2 = split[1]
if len(split) > 2 {
parts.Part3 = split[2]
}
}
}
fmt.Println(parts)
}
输出:
{part1 part2 part3}
英文:
For example,
package main
import (
"fmt"
"strings"
)
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
func main() {
str := "part1/part2/part3"
split := strings.Split(str, "/")
var parts MyStruct
if len(split) > 0 {
parts.Part1 = split[0]
if len(split) > 1 {
parts.Part2 = split[1]
if len(split) > 2 {
parts.Part3 = split[2]
}
}
}
fmt.Println(parts)
}
Output:
{part1 part2 part3}
答案4
得分: 0
扩展dyoo的答案,使用更短的语法和重命名的类型,因为我为了这两个原因绕过了它,但它是最可扩展和可靠的解决方案。如果您需要从3个元素更改为n个元素,只需要更改结构定义和初始化即可。当需要为字符串切片设置默认值时,StrSlice类型也非常可重用。
package main
import (
"fmt"
"strings"
)
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
type StrSlice []string
func (s StrSlice) Get(i int) string {
if i >= 0 && i < len(s) {
return s[i]
}
return ""
}
func main() {
str := "part1/part2/part3"
slice := StrSlice(strings.Split(str, "/"))
parts := MyStruct{slice.Get(0),slice.Get(1),slice.Get(2)}
fmt.Println(parts)
}
英文:
Expanding on dyoo's answer with shorter syntax and renamed types as I bypassed it for these two reasons, however it is the most extensible and reliable solution. The real benefit comes if you need to change from 3 to n elements, all that is required is a change to your struct definition and initialisation. StrSlice type is also very reusable when ever default values are required for a slice of strings.
package main
import (
"fmt"
"strings"
)
type MyStruct struct {
Part1 string
Part2 string
Part3 string
}
type StrSlice []string
func (s StrSlice) Get(i int) string {
if i >= 0 && i < len(s) {
return s[i]
}
return ""
}
func main() {
str := "part1/part2/part3"
slice := StrSlice(strings.Split(str, "/"))
parts := MyStruct{slice.Get(0),slice.Get(1),slice.Get(2)}
fmt.Println(parts)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论