将高类型向下转换为低类型

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

downcast higher-type to lower

问题

除了手动复制内部Box值之外,是否有一种语言特性可以将RatedBox向下转换为Box

type Box struct {
    Name string
}

type RatedBox struct {
    Box
    Points int
}

func main() {
    rated := RatedBox{Box: Box{Name: "foo"}, Points: 10}
    
    box := Box(rated) // 不起作用
}

[go-playground](https://play.golang.org/p/iNpPgiIWqv)

// 对于具有更多成员的结构来说,这种方法可行,但比较冗长
box := Box{Name: rated.Name}
英文:

Is there beside copying the inner Box value by hand a language feature to down-cast RatedBox into a Box?

type Box struct {
	Name string
}

type RatedBox struct {
	Box
	Points int
}

func main() {
	rated := RatedBox{Box: Box{Name: "foo"}, Points: 10}
    
	box := Box(rated) // does not work
}

go-playground

// works, but is quite verbose for structs with more members
box := Box{Name: rated.Name}

答案1

得分: 9

在结构体中嵌入一个类型会向结构体添加一个字段,你可以使用未限定的类型名称来引用它(未限定意味着省略包名和可选的指针符号)。

例如:

box := rated.Box
fmt.Printf("%T %+v", box, box)

输出结果(在Go Playground上尝试):

main.Box {Name:foo}

请注意,赋值会复制值,所以box局部变量将保存RatedBox.Box字段的值的副本。如果你希望它们是“相同的”(指向相同的Box值),可以使用指针,例如:

box := &rated.Box
fmt.Printf("%T %+v", box, box)

但是这里box的类型当然是*Box

或者你可以选择嵌入指针类型:

type RatedBox struct {
	*Box
	Points int
}

然后(在Go Playground上尝试):

rated := RatedBox{Box: &Box{Name: "foo"}, Points: 10}

box := rated.Box
fmt.Printf("%T %+v", box, box)

最后两个输出结果:

*main.Box &{Name:foo}
英文:

Embedding a type in a struct adds a field to the struct, and you can use the unqualified type name to refer to it (unqualified means omit the package name and the optional pointer sign).

For example:

box := rated.Box
fmt.Printf("%T %+v", box, box)

Output (try it on the Go Playground):

main.Box {Name:foo}

Note that assignment copies the value, so the box local variable will hold a copy of the value of the RatedBox.Box field. If you want them to be the "same" (to point to the same Box value), use a pointer, e.g.:

box := &rated.Box
fmt.Printf("%T %+v", box, box)

But here of course type of box will be *Box.

Or you may choose to embed the pointer type:

type RatedBox struct {
	*Box
	Points int
}

And then (try it on the Go Playground):

rated := RatedBox{Box: &Box{Name: "foo"}, Points: 10}

box := rated.Box
fmt.Printf("%T %+v", box, box)

Output of the last 2:

*main.Box &{Name:foo}

huangapple
  • 本文由 发表于 2017年7月26日 21:14:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/45328119.html
匿名

发表评论

匿名网友

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

确定