日前,因为一个业务需要,在struct聚合上百万个接口(因为没有基类、子类,只有通过接口来代替基类作用)的时候,出现了非常意外的编译提示。初步判定是接口数量有限制导致。
```code
调试环境:go1.6.2 darwin/amd64
代码如下:
```
```code
package main
import (
"fmt"
)
const arraynum = 1 << 20 //①,数组的大小定义
type I interface {
GetXY() (x, y int16)
}
type I_impl struct {
x, y int16
}
func (this *I_impl) GetXY() (x, y int16) {
return this.x, this.y
}
type World struct {
Name string
grids [arraynum]I //②,大数组
elem map[int32]*Element
}
func (this *World) String() string {
output := this.Name + " output:\n"
for k, v := range this.elem {
output = output + fmt.Sprintf("%v:%v,", k, v)
}
return output
}
func NewWorld(name string) *World {
world := &World{
Name: name,
elem: make(map[int32]*Element), //③,当world的grids数组较大,只有这里初始化
}
//world.elem = make(map[int32]*Element) //④,当world的grids数组较大,只有这里初始化
return world
}
func (this *World) AddElement(player *Element) {
if player == nil {
return
}
this.elem[player.ID] = player
}
type Element struct {
ID int32
}
func NewElement(id int32) *Element {
return &Element{
ID: id,
}
}
func main() {
world := NewWorld("world 1")
e := NewElement(1)
world.AddElement(e)
fmt.Println(world)
}
```
现在问题来了:
```code
直接运行,将会编译错误:
# command-line-arguments
src/forstudy/test/main.go:36: internal compiler error: haspointers: unexpected type, elem map[int32]*Element
Process finished with exit code 2
```
经过反复尝试,发现以下几种操作可以解决:
```code
方法一:屏蔽③,启用④,修改struct初始化的方式。
```
```code
方法二:将①所在行的变量值改小,减少数组的数量,比如从100万,修改为50万。但这种修改,相当于限制了应用。
```
```code
方法三:将②所在行的数组的值改为实现类,而不用interface,则没有限制。
```
由于设计上需要有一定的继承来减少耦合,暂时只有采用方法一。这时,问题就来了:
```code
1. 按照平时查找的资料,③与④是等价的。为何编译会出现不一样的结果?
2. 大数组怎么会影响到map的初始化?
```
[fix diff](https://github.com/golang/go/commit/fb2af2b35b8d2ad832f2398e981ea78c64b0663b)
#6
更多评论