英文:
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
}
// 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}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论