如何在golang中为嵌入式接口分配对象

时间:2017-06-06 18:55:11

标签: go

我试图将类型为Baz的结构数组分配给嵌入在Foo类型的第二个结构中的Bar类型的接口数组。我无法在这里或其他地方使用谷歌搜索确切的信息。我提供了一个最低限度的工作示例。

我收到以下错误:

$ go run main.go

./ main.go:38:不能使用baz(类型[] * Baz)作为NewFoo参数中的类型[] Bar

如果我的代码不是惯用的,我很抱歉,如果我没有确切地确认发布问题的标准,这是我的第一篇文章。

package main


import (
    "fmt"
)
type Foo struct {
    b []Bar
}



type Baz struct {
    a, b int
}

type Bar interface {
    Multiply() int
}

func (baz *Baz) Multiply() int{
    return baz.a * baz.b
}

func NewFoo(bar []Bar) *Foo{
    return &Foo{b: bar}
}
func NewBaz() []*Baz {
    bazes := make([]*Baz, 2)
    bazes[0] = &Baz{a: 1, b: 2}
    bazes[1] = &Baz{a: 3, b: 4}
    return bazes
}

func main() {

    baz := NewBaz()
    foo := NewFoo(baz)
    for _, f := range foo.b {
        fmt.Println("Foo.Multiply ", f.Multiply())
    }
}

更新:我在进一步阅读并理解建议的相关帖子后批准了重复投票。感谢那些指引我朝这个方向发展的人。对于未来感兴趣的读者,我的最终实现与我的用例一致如下:

package main

import (
    "fmt"
)

type Foo struct {
    b []Bar
}

type Baz struct {
    a, b int
}

type Bar interface { //
    Multiply() int
}

func (baz *Baz) Multiply() int {
    return baz.a * baz.b
}

func NewFoo(bar []*Baz) *Foo{
    f := &Foo{}
    f.b = make([]Bar, 2)
    fmt.Println("len(bar) ", len(bar), "len(f.b)", len(f.b) )
    for i, _ := range f.b {
        f.b[i] = bar[i]

    }
    return f
}

func MakeBaz() []*Baz {
    bazes := make([]*Baz, 2)
    bazes[0] = NewBaz(1, 2)
    bazes[1] = NewBaz(3, 4)
    return bazes
}

func NewBaz(aa, bb int) *Baz {
    return &Baz{a: aa, b: bb}
}

func main() {
    baz := MakeBaz()
    foo := NewFoo(baz)
    fmt.Printf("%v\n", foo)
    for _, f := range foo.b {
        fmt.Println("Foo.Multiply ", f.Multiply())
    }
}

2 个答案:

答案 0 :(得分:0)

有几种不同的方法可以做到这一点,但最直接的方法是将Baz类型嵌入Bar中。 Baz现在可以乘以()并有两个字段(a,b)。您的代码看起来像这样:

package main

import (
    "fmt"
)

type Foo struct {
    b []*Baz
}

type Baz struct {
    Bar
    a, b int
}

type Bar interface {
    Multiply() int
}

func (baz *Baz) Multiply() int {
    return baz.a * baz.b
}

func NewFoo(bar []*Baz) *Foo {
    return &Foo{b: bar}
}
func NewBaz() []*Baz {
    bazes := make([]*Baz, 2)
    bazes[0] = &Baz{a: 1, b: 2}
    bazes[1] = &Baz{a: 3, b: 4}
    return bazes
}

func main() {
    baz := NewBaz()
    foo := NewFoo(baz)
    for _, f := range foo.b {
        fmt.Println("Foo.Multiply ", f.Multiply())
    }
}

GoPlay: https://play.golang.org/p/lia0ZS81TO

顺便说一下,这是第一个问题。

答案 1 :(得分:0)

您收到的错误:

  

不能使用baz(类型[] * Baz)作为类型[] Bar

因为Go不会让你将Baz数组分配给Bar数组,即使它允许你将Baz分配给Bar变量。

要以更简单的形式看到这一点,这很好用:

var oneBaz *Baz = &Baz{a: 1, b: 2} 
var oneBar Bar = oneBaz

因为Baz类型满足Bar接口,你可以将Baz对象分配给Bar变量。

但是这不起作用(即使看起来它可以起作用):

var bazArray []*Baz = make([]*Baz, 2)
var barArray []Bar = bazArray

它会抛出您所看到的相同错误。

为了完成这项工作,您可能需要实施此相关问题中列出的解决方案之一:

Type converting slices of interfaces in go