2013-07-30 39 views
3

我有一个结构如下:Golang - 映射的可变长度数组一个struct

type MyStruct struct { 
    Part1 string 
    Part2 string 
    Part3 string 
} 

我有一个字符串由我想要映射到这个斜线分隔:

part1/part2/part3 

然而,该字符串可能只包含1部分,如part1或part1/part2这样的两部分

如果有任何部分丢失,它将被映射为空字符串。

我很新,所以想知道实现这个目标的最好方法是什么。通常我会分割字符串并检查长度以知道该怎么做。有没有更好的方法来做到这一点?

回答

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} 
+0

是否无法检查元素是否存在,如split split [0] {//在此做某事} –

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) 
} 
4
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")) 
} 

Playground


输出:

&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"} 
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) 

}