英文:
Type assertion failed with correct casting from interface{} in golang
问题
以下是我从下面的简单重现案例中得到的输出:
2015/06/22 21:09:50 ok: false
2015/06/22 21:09:50 stub: *main.Stub <nil>
显然,存根被正确标记为指向Stub类型的指针,但类型转换失败。我正在尝试更新数组的内容。
package main
import "log"
const BUFFER_SIZE = 8
type Value struct {
value int
}
func (v Value) Value() int { return v.value }
func (v *Value) SetValue(value int) { v.value = value }
type Stub struct {
Value
testString string
}
type StubFactory struct{}
type FactoryInterface interface {
NewInstance(size int) []interface{}
}
func (factory StubFactory) NewInstance(size int) []interface{} {
stubs := make([]interface{}, size)
for i, _ := range stubs {
stubs[i] = &Stub{Value: Value{i}, testString: ""}
}
return stubs
}
type Buffer struct {
values []interface{}
}
func NewBuffer(factory FactoryInterface, size int) *Buffer {
return &Buffer{values: factory.NewInstance(size)}
}
func (buf *Buffer) Get(index int) interface{} {
return &buf.values[index]
}
func main() {
stubFactory := &StubFactory{}
buffer := NewBuffer(stubFactory, BUFFER_SIZE)
index := 0
if stub, ok := buffer.Get(index).(*Stub); ok { // THIS FAILS :-(
log.Printf("ok: %+v\n", ok)
log.Printf("stub: %T %+v\n", stub, stub)
stub.SetValue(1234)
log.Printf("value:%+v\n", buffer.Get(index)) // I WANT "1234"
} else {
log.Printf("ok: %+v\n", ok)
log.Printf("stub: %T %+v\n", stub, stub) // but this shows the right type
}
}
英文:
Here is the output I am getting from the simple repro case below:
2015/06/22 21:09:50 ok: false
2015/06/22 21:09:50 stub: *main.Stub <nil>
Clearly the stub is correctly marked as pointer to Stub type but the casting failed. I am trying to update the content of the array.
package main
import "log"
const BUFFER_SIZE = 8
type Value struct {
value int
}
func (v Value) Value() int { return v.value }
func (v *Value) SetValue(value int) { v.value = value }
type Stub struct {
Value
testString string
}
type StubFactory struct{}
type FactoryInterface interface {
NewInstance(size int) []interface{}
}
func (factory StubFactory) NewInstance(size int) []interface{} {
stubs := make([]interface{}, size)
for i, _ := range stubs {
stubs[i] = &Stub{Value: Value{i}, testString: ""}
}
return stubs
}
type Buffer struct {
values []interface{}
}
func NewBuffer(factory FactoryInterface, size int) *Buffer {
return &Buffer{values: factory.NewInstance(size)}
}
func (buf *Buffer) Get(index int) interface{} {
return &buf.values[index]
}
func main() {
stubFactory := &StubFactory{}
buffer := NewBuffer(stubFactory, BUFFER_SIZE)
index := 0
if stub, ok := buffer.Get(index).(*Stub); ok { // THIS FAILS :-(
log.Printf("ok: %+v\n", ok)
log.Printf("stub: %T %+v\n", stub, stub)
stub.SetValue(1234)
log.Printf("value:%+v\n", buffer.Get(index)) // I WANT "1234"
} else {
log.Printf("ok: %+v\n", ok)
log.Printf("stub: %T %+v\n", stub, stub) // but this shows the right type
}
}
答案1
得分: 5
错误是:
func (buf *Buffer) Get(index int) interface{} {
return &buf.values[index]
}
你想要的是:
func (buf *Buffer) Get(index int) interface{} {
return buf.values[index]
}
当你返回 &buf.values[index] 时,你返回的是一个指向接口的指针。这在某种意义上是一个 *(*Stub)。
英文:
The error is:
func (buf *Buffer) Get(index int) interface{} {
return &buf.values[index]
}
You want to do:
func (buf *Buffer) Get(index int) interface{} {
return buf.values[index]
}
When you return &buf.values[index] you are returning a pointer to an interface. Which is a *(*Stub) (in a sense)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论