2016-09-14 36 views
0

我有两个结构:Golang转换对象列表串

type A struct { 
    BankCode   string `json:"bankCode"` 
    BankName   string `json:"bankName"` 
} 

和:

type B struct { 
    A 
    extra   string `json:" extra"` 
} 

两片:
listsA []AlistsB []B 我想从listAlistB得到bankCodesbankcodes只包含bankcodes。这是一个[]string

这将是如此简单,使用两个功能。

func getBankCodes(data []A) []string { 
    res := make([]string, len(data)) 
    for i := 0; i < len(data); i++ { 
     res[i] = data[i].BankCode 
    } 
    return res 
} 

func getBankCodes(data []B) []string { 
    res := make([]string, len(data)) 
    for i := 0; i < len(data); i++ { 
     res[i] = data[i].BankCode 
    } 
    return res 
} 

如何使用一个常用函数?

回答

0

那么干净的解决方案就是使用一个接口,因为go不支持经典继承,所以像[]parentclass这样的东西不能工作。但是接口只能描述不是通用字段的函数,所以你必须实现一个Getter(本质上)。

// GetBankCoder provides a function that gives the BankCode 
type GetBankCoder interface { 
    getBankCode() string 
} 

// implement GetBankCoder for A (and indirectly for B) 
func (a A) getBankCode() string { 
    return a.BankCode 
} 

,使您的getBankCodes在该接口类型的工作,注意函数的参数以及循环内的语句:

func getBankCodes(data []GetBankCoder) []string { // <-- changed 
    res := make([]string, len(data)) 
    for i := 0; i < len(data); i++ { 
     res[i] = data[i].getBankCode()    // <-- changed 
    } 
    return res   
} 

还有其他的解决方案,其中,函数参数是interface{}然后反射用来确保你实际上可以做.BankCode,但我不喜欢那些,因为它们不会增加更多的清晰度。

......但是,我不能让golang操场正确地工作,而不必先把它放入[]GetBankCoder var,然后再给它函数。

banks := make([]GetBankCoder, 0) 
banks = append(banks, A{ BankCode: "ABC", BankName: "ABC Bank"}) 
getBankCodes(banks) 
+0

谢谢您的回答 –

0

你可以使用一个共同的功能,像这样:

func BankCodes(data interface{}) []string { 
    if reflect.TypeOf(data).Kind() != reflect.Slice { 
     panic("err: data is not slice") 
    } 
    slice := reflect.Indirect(reflect.ValueOf(data)) 
    res := make([]string, slice.Len()) 
    for i := 0; i < slice.Len(); i++ { 
     a := slice.Index(i).Interface().(BankCoder) 
     res[i] = a.Bankcode() 
    } 
    return res 
} 

代码(试穿The Go Playground):

package main 

import (
    "fmt" 
    "reflect" 
) 

func main() { 
    bs := []B{B{A{"BC1", "BN"}, "e"}, B{A{"BC2", "BN"}, "e"}} 
    strs := BankCodes(bs) 
    fmt.Println(strs) 

    as := []A{A{"AC1", "BN"}, A{"AC2", "BN"}} 
    strs2 := BankCodes(as) 
    fmt.Println(strs2) 

} 

func BankCodes(data interface{}) []string { 
    if reflect.TypeOf(data).Kind() != reflect.Slice { 
     panic("err: data is not slice") 
    } 
    slice := reflect.Indirect(reflect.ValueOf(data)) 
    res := make([]string, slice.Len()) 
    for i := 0; i < slice.Len(); i++ { 
     a := slice.Index(i).Interface().(BankCoder) 
     res[i] = a.Bankcode() 
    } 
    return res 
} 

type A struct { 
    BankCode string `json:"bankCode"` 
    BankName string `json:"bankName"` 
} 

type B struct { 
    A 
    extra string `json:" extra"` 
} 
type BankCoder interface { 
    Bankcode() string 
} 

func (a A) Bankcode() string { 
    return a.BankCode 
} 
+0

谢谢您的回答 –

+0

@ starzhang:不客气。 – 2016-09-14 11:05:37