我想知道以下函数lengthAA
和lengthBB
如何简化为一个函数。注意在这两个函数中它只是计算数组的长度,它只是一个例子,可能比这更复杂。理想情况下,我只想要一个用于相同目的的函数(在本例中为len
),但可以将不同的struct
作为变量。
type A struct {
id string
}
type AA struct {
ids []A
}
type B struct {
id string
value bool
}
type BB struct {
ids []B
}
func lengthAA(aa AA) int {
return len(aa)
}
func lengthBB(bb BB) int {
return len(bb)
}
答案 0 :(得分:3)
执行此操作的Go方式是AA
和BB
实现常用方法。然后,length
将接受包含相同功能签名的接口。例如:
package main
import (
"fmt"
)
type Lengther interface {
Length() int
}
type A struct {
id string
}
type AA struct {
ids []A
}
func (a *AA) Length() int {
return len(a.ids)
}
type B struct {
id string
value bool
}
type BB struct {
ids []B
}
func (b *BB) Length() int {
return len(b.ids)
}
func length(l Lengther) int {
return l.Length()
}
func main() {
aa := &AA{
ids: make([]A, 10),
}
bb := &BB{
ids: make([]B, 34),
}
fmt.Println(length(aa))
fmt.Println(length(bb))
}
答案 1 :(得分:1)
1-使用两个独立的接收方法length()
,就像这样的工作示例代码(这是惯用的Go):
package main
import "fmt"
func (v *AA) length() int {
return len(v.ids)
}
func (v *BB) length() int {
return len(v.ids)
}
func main() {
aa := AA{[]A{A{"id"}, A{"id2"}}}
fmt.Println(aa.length()) // 2
bb := BB{[]B{B{"id", true}, B{"id2", true}}}
fmt.Println(bb.length()) // 2
}
type A struct {
id string
}
type AA struct {
ids []A
}
type B struct {
id string
value bool
}
type BB struct {
ids []B
}
2-使用一个length(aa interface{})
函数,就像这个工作示例代码一样(在某些用例中这很有用):
package main
import "fmt"
func length(aa interface{}) int {
switch v := aa.(type) {
case AA:
return len(v.ids)
case BB:
return len(v.ids)
}
return -1
}
func main() {
aa := AA{[]A{A{"id"}, A{"id2"}}}
fmt.Println(length(aa)) // 2
bb := BB{[]B{B{"id", true}, B{"id2", true}}}
fmt.Println(length(bb)) // 2
}
type A struct {
id string
}
type AA struct {
ids []A
}
type B struct {
id string
value bool
}
type BB struct {
ids []B
}
3-使用reflect
和一个length(v interface{})
函数,就像这个工作示例代码一样(在某些用例中这很有用):
package main
import "fmt"
import "reflect"
func length(v interface{}) int {
return reflect.ValueOf(v).FieldByName("ids").Len()
}
func main() {
aa := AA{[]A{A{"id"}, A{"id2"}}}
fmt.Println(length(aa)) // 2
bb := BB{[]B{B{"id", true}, B{"id2", true}}}
fmt.Println(length(bb)) // 2
}
type A struct {
id string
}
type AA struct {
ids []A
}
type B struct {
id string
value bool
}
type BB struct {
ids []B
}
输出:
2
2
答案 2 :(得分:0)
这段代码实际上不会编译,因为len(aa)
会将结构传递给len
,这会失败。但我认为我得到了你想要做的事情,而最好的方法是使用最接近的东西Go继承,这实际上只是结构嵌入。
通过制作一个可嵌入的结构体,并且让每个具有相似特征的结构嵌入它,你可以减少代码的行数,尽管“简化”可能有点延伸。
type HasIDs struct {
Ids []string
}
type AA struct {
HasIDs
OtherValues []int
}
type BB struct {
HasIDs
OtherValues []byte
}
此时,结构AA
和BB
的值均为Ids []string
。现在,您可以为HasIDs
结构提供一个两个结构都应该能够调用的方法。
func (hasIds HasIDs) length() {
return len(hasIds.Ids)
}
在任何使用方法嵌入结构的struct上调用该方法。
a1 := AA{}
aLength := a1.length()
以下是一个有效的代码示例:https://play.golang.org/p/ys_CN_L_cr