Golang – 将可变长度的数组映射到结构体

huangapple go评论77阅读模式
英文:

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 (
	&quot;fmt&quot;
	&quot;strings&quot;
)

type Wrap []string

func (w Wrap) Get(i int) string {
	if 0 &lt;= i &amp;&amp; i &lt; len(w) {
		return w[i]
	}
	return &quot;&quot;
}

type MyStruct struct {
	Part1 string
	Part2 string
	Part3 string
}

func main() {
	str := &quot;part1/part2/part3&quot;
	split := Wrap(strings.Split(str, &quot;/&quot;))
	var parts MyStruct
	parts.Part1 = split.Get(0)
	parts.Part2 = split.Get(1)
	parts.Part3 = split.Get(2)
	fmt.Println(parts)

	str = &quot;part1/part2&quot;
	split = Wrap(strings.Split(str, &quot;/&quot;))
	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 (
	&quot;fmt&quot;
	&quot;strings&quot;
)

type MyStruct struct {
	Part1 string
	Part2 string
	Part3 string
}

func (m *MyStruct) set(s string) *MyStruct {
	p := []*string{&amp;m.Part1, &amp;m.Part2, &amp;m.Part3}
	for i, v := range strings.Split(s+&quot;//&quot;, &quot;/&quot;)[:3] {
		*p[i] = v
	}
	return m
}

func main() {
	var v MyStruct
	fmt.Printf(&quot;%#v\n&quot;, v.set(&quot;foo&quot;))
	fmt.Printf(&quot;%#v\n&quot;, v.set(&quot;&quot;))
	fmt.Printf(&quot;%#v\n&quot;, v.set(&quot;bar/baz&quot;))
	fmt.Printf(&quot;%#v\n&quot;, v.set(&quot;alpha//omega&quot;))
	fmt.Printf(&quot;%#v\n&quot;, v.set(&quot;/var/mail&quot;))
}

Playground


Output:

&amp;main.MyStruct{Part1:&quot;foo&quot;, Part2:&quot;&quot;, Part3:&quot;&quot;}
&amp;main.MyStruct{Part1:&quot;&quot;, Part2:&quot;&quot;, Part3:&quot;&quot;}
&amp;main.MyStruct{Part1:&quot;bar&quot;, Part2:&quot;baz&quot;, Part3:&quot;&quot;}
&amp;main.MyStruct{Part1:&quot;alpha&quot;, Part2:&quot;&quot;, Part3:&quot;omega&quot;}
&amp;main.MyStruct{Part1:&quot;&quot;, Part2:&quot;var&quot;, Part3:&quot;mail&quot;}

答案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 (
	&quot;fmt&quot;
	&quot;strings&quot;
)

type MyStruct struct {
	Part1 string
	Part2 string
	Part3 string
}

func main() {
	str := &quot;part1/part2/part3&quot;
	split := strings.Split(str, &quot;/&quot;)
	var parts MyStruct
	if len(split) &gt; 0 {
		parts.Part1 = split[0]
		if len(split) &gt; 1 {
			parts.Part2 = split[1]
			if len(split) &gt; 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 (
    &quot;fmt&quot;
    &quot;strings&quot;
)

type MyStruct struct {
    Part1 string
    Part2 string
    Part3 string
}

type StrSlice []string

func (s StrSlice) Get(i int) string {
    if i &gt;= 0 &amp;&amp; i &lt; len(s) {
        return s[i]
    }
    return &quot;&quot;
}

func main() {

    str := &quot;part1/part2/part3&quot;
    slice := StrSlice(strings.Split(str, &quot;/&quot;))
    parts := MyStruct{slice.Get(0),slice.Get(1),slice.Get(2)}
    fmt.Println(parts)

}

huangapple
  • 本文由 发表于 2013年7月30日 08:28:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/17936456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定