创建一个扩展类型的数组

huangapple go评论86阅读模式
英文:

Creating a array of extended types

问题

我有一个结构体A,用结构体B来扩展(“子类化”)它,就像这样:

package main

type A struct {
    x int
}

type B struct {
    A
    y int
}

我想创建一个数组,可以向其中添加A或B,以便使这段代码工作:

func main() {
    var m [2]B

    m[0] = B { A { 1 }, 2 }
    m[0].x = 0
    m[0].y = 0

    m[1] = A { 3 }
    m[1].x = 0
}

但是它不起作用。如果我创建类型为B的数组,我会得到“无法将结构体字面量(类型A)用作类型B的赋值”。如果我尝试创建类型为A的数组,我会得到相同的错误(只是类型颠倒)。

所以我的问题是:数组应该是哪种类型?

英文:

I have a struct A, extending ("subclassing") it with struct B, like this:

package main

type A struct {
    x int
}

type B struct {
    A
    y int
}

I want to create a array where I can append A or B to it, so that this code works:

func main() {
    var m [2]B

    m[0] = B { A { 1 }, 2 }
    m[0].x = 0
    m[0].y = 0

    m[1] = A { 3 }
    m[1].x = 0
}

It doesn't. If I create the array of the type B, I get "cannot use struct literal (type A) as type B in assignment". If I try to create the array of the type A, I get the the same error (just with the types reversed).

So my question is: which type should the array be?

答案1

得分: 3

你可以使用struct值。例如,

package main

import "fmt"

type A struct {
    x int
}

type B struct {
    A
    y int
}

func main() {
    var m []interface{}
    m = append(m, B{A{1}, 2})
    m = append(m, A{3})
    fmt.Println(m[0], m[1])
    if b, ok := m[0].(B); ok {
        b.x = 0
        b.y = 0
        m[0] = b
    }
    if a, ok := m[1].(A); ok {
        a.x = 0
        m[1] = a
    }
    fmt.Println(m[0], m[1])
}
    
输出:
{{1} 2} {3}
{{0} 0} {0}

或者,你可以使用struct指针。例如,

package main

import "fmt"

type A struct {
    x int
}

type B struct {
    A
    y int
}

func main() {
    var m []interface{}
    m = append(m, &B{A{1}, 2})
    m = append(m, &A{3})
    fmt.Println(m[0], m[1])
    if b, ok := m[0].(*B); ok {
        b.x = 0
        b.y = 0
    }
    if a, ok := m[1].(*A); ok {
        a.x = 0
    }
    fmt.Println(m[0], m[1])
}

输出:
&{{1} 2} &{3}
&{{0} 0} &{0}
英文:

You could use struct values. For example,

package main

import "fmt"

type A struct {
	x int
}

type B struct {
	A
	y int
}

func main() {
	var m []interface{}
	m = append(m, B{A{1}, 2})
	m = append(m, A{3})
	fmt.Println(m[0], m[1])
	if b, ok := m[0].(B); ok {
		b.x = 0
		b.y = 0
		m[0] = b
	}
	if a, ok := m[1].(A); ok {
		a.x = 0
		m[1] = a
	}
	fmt.Println(m[0], m[1])
}
    
Output:
{{1} 2} {3}
{{0} 0} {0}

Or, you could use struct pointers. For example,

package main

import "fmt"

type A struct {
	x int
}

type B struct {
	A
	y int
}

func main() {
	var m []interface{}
	m = append(m, &B{A{1}, 2})
	m = append(m, &A{3})
	fmt.Println(m[0], m[1])
	if b, ok := m[0].(*B); ok {
		b.x = 0
		b.y = 0
	}
	if a, ok := m[1].(*A); ok {
		a.x = 0
	}
	fmt.Println(m[0], m[1])
}

Output:
&{{1} 2} &{3}
&{{0} 0} &{0}

答案2

得分: 2

你需要将数组类型定义为interface{}而不是B。然后你可以在其中存储两种类型。这是唯一的方法来实现这个。如果两种类型都实现了特定的接口,那么你可以将其类型化为该接口,而不是通用的interface{}

英文:

You'll want to define the array type to interface{} rather than B. Then you can store both types in there. That's the only way to accomplish this. If both types implement a specific interface, then you can type to that instead of the generic interface{}

huangapple
  • 本文由 发表于 2011年7月12日 04:01:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/6655811.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定