0

我有两个结构:

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

和:

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

和两片: 我想从
listsA []Aand得到。只包含. 它是一个listsB []BbankCodeslistAlistBbankcodesbankcodes[]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
}

如何使用一个常用功能?

4

2 回答 2

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
}

代码(试试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
}
于 2016-09-14T10:27:16.007 回答
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,但我不喜欢那些,因为它们也没有增加清晰度。

[]GetBankCoder...但是,在将其提供给函数之前,如果不先将其放入 var 中,我无法让 golang 操场正常工作。

banks := make([]GetBankCoder, 0)
banks = append(banks, A{ BankCode: "ABC", BankName: "ABC Bank"})
getBankCodes(banks)
于 2016-09-14T10:07:03.657 回答