英文:
How can I use interface{} as a wildcard type?
问题
场景是传递具有共同字段的类似结构,并将其设置为作为参数传递的值:
package main
type A struct {
Status int
}
type B struct {
id string
Status int
}
// 可以通过值传递,因为内容仅在此函数内部使用
func foo(v interface{}, status int) {
switch t := v.(type) {
case A, B:
t.Status = status // 错误 :-(
}
}
func main() {
a := A{}
foo(a, 0)
b := B{}
b.id = "x"
foo(b, 1)
}
令我沮丧的是,我得到了这个错误:
# command-line-arguments
./test.go:15: t.Status undefined (type interface {} has no field or method Status)
如果类型转换将 interface{} 转换为底层类型,那么我做错了什么?
英文:
The scenario is to pass similar structs with common fields and set those to values passed as params:
package main
type A struct {
Status int
}
type B struct {
id string
Status int
}
// It's okay to pass by value because content is only used inside this
func foo(v interface{}, status int) {
switch t := v.(type) {
case A, B:
t.Status = status // ERROR :-(
}
}
func main() {
a := A{}
foo(a, 0)
b := B{}
b.id = "x"
foo(b, 1)
}
To my dismay, I am getting this error:
➜ test go run test.go
# command-line-arguments
./test.go:15: t.Status undefined (type interface {} has no field or method Status)
What am I doing wrong if the typecast converts interface{} to the underlying type?
答案1
得分: 5
即使A和B都有一个状态字段,它们在类型系统中并不可互换。你必须为它们分别设置不同的情况。
case A:
t.Status = status
case B:
t.Status = status
}
或者,你可以使用一个实际的接口:
type HasStatus interface {
SetStatus(int)
}
type A struct {
Status int
}
func (a *A) SetStatus(s int) { a.Status = s }
func foo(v HasStatus, status int) {
v.SetStatus(status)
}
如果你有多个类型都有一组共同的字段,你可以使用嵌入结构体:
type HasStatus interface {
SetStatus(int)
}
type StatusHolder struct {
Status int
}
func (sh *StatusHolder) SetStatus(s int) { sh.Status = s }
type A struct {
StatusHolder
}
type B struct {
id string
StatusHolder
}
英文:
Even though A and B both have a status field they are not interchangeable to the type system. You must have separate cases for each of them.
case A:
t.Status = status
case B:
t.Status = status
}
Alternatively, you could use an actual interface:
type HasStatus interface {
SetStatus(int)
}
type A struct {
Status int
}
func (a *A) SetStatus(s int) { a.Status = s }
func foo(v HasStatus, status int) {
v.SetStatus(status)
}
If you have multiple types that all have a common set of fields you may want to use an embedded struct:
type HasStatus interface {
SetStatus(int)
}
type StatusHolder struct {
Status int
}
func (sh *StatusHolder) SetStatus(s int) { sh.Status = s }
type A struct {
StatusHolder
}
type B struct {
id string
StatusHolder
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论