英文:
Embed two structs with the same name in a struct
问题
如何在结构体中嵌入两个同名类型?例如:
type datastore struct {
*sql.Store
*file.Store
}
这会导致duplicate field Store
的错误。我知道这是有道理的,因为你将无法引用嵌入字段ds.Store
,但是你如何解决这个问题呢?
为了澄清,我想要在datastore
中实现一个接口。为此,需要两个结构体,因为它们的方法互补,以创建接口。我有哪些替代方案?
英文:
How do you embed two types of the same name in a struct? For instance:
type datastore {
*sql.Store
*file.Store
}
Results in duplicate field Store
. I know this makes sense, since you wouldn't be able to refer to the embedded field ds.Store
but how do you accomplish this anyway?
To clarify, I want to implement an interface with datastore
. For that both structs are needed as their methods complement each other to create the interface. What alterantives do I have?
答案1
得分: 19
使用类型别名(type alias)的示例:
type SqlStore = sql.Store // 这是一个类型别名
type datastore struct {
*SqlStore
*file.Store
}
类型别名并不会创建一个与所创建的类型不同的新类型。它只是为sql.Store
所表示的类型引入了一个别名SqlStore
,作为该类型的替代拼写方式。
英文:
Use a type alias, example:
type SqlStore = sql.Store // this is a type alias
type datastore struct {
*SqlStore
*file.Store
}
A type alias doesn’t create a new distinct type different from the type it’s created from. It just introduces an alias name sqlStore
, an alternate spelling, for the type denoted by sql.Store
.
答案2
得分: 5
你可以尝试将whatever.Store
包装成具有不同名称的类型:
import (
"os"
"whatever/sql"
)
type SqlStore struct {
*sql.Store
}
type FileStore struct {
*os.File
}
type DataStore struct {
SqlStore
FileStore
}
请注意,Go 1.9可能会支持类型别名:参见这个链接和这个链接。我不确定这是否对你有帮助,但了解一下可能会很有趣。
英文:
You can try to first wrap your whatever.Store
into distinct-named types:
import (
"os"
"whatever/sql"
)
type SqlStore struct {
*sql.Store
}
type FileStore struct {
*os.File
}
type DataStore struct {
SqlStore
FileStore
}
Note that Go 1.9 might gain support for type aliases: see this and this. I'm not sure that would help in your case but might be interesting to learn about.
答案3
得分: 2
你可以在两个不同的子结构中引用一个字段,即使它们作为匿名字段包含在内:
package main
import "fmt"
type A struct {
x int32
}
type B struct {
x int32
}
type C struct {
A
B
}
func main() {
c := C{A{1}, B{2}}
//fmt.Println(c.x) // 错误,模棱两可
fmt.Println(c.A.x) // 正确,输出 1
fmt.Println(c.B.x) // 正确,输出 2
}
英文:
You can indeed refer to a field even if present in two different substructures included as anonymous fields:
package main
import "fmt"
type A struct {
x int32
}
type B struct {
x int32
}
type C struct {
A
B
}
func main() {
c := C{A{1}, B{2}}
//fmt.Println(c.x) // Error, ambiguous
fmt.Println(c.A.x) // Ok, 1
fmt.Println(c.B.x) // Ok, 2
}
答案4
得分: 1
你可以在结构体中简单地为这两个“Store”命名不同的名称。当你在结构体中没有为嵌入的结构体字段命名时,它默认为嵌入结构体的名称。所以,在这里,你有两个名为“Store”的字段,但你可以很容易地使名称明确。所以使用以下代码:
package main
import (
"file"
"fmt"
"sql"
)
type Datastore struct {
sqlStore *sql.Store
fileStore *file.Store
}
func main() {
ds := Datastore{&sql.Store{SqlStoreName: "MySQLStore"}, &file.Store{FileStoreName: "MyFileStore"}}
fmt.Println(ds.sqlStore.SqlStoreName, ds.fileStore.FileStoreName)
}
这对我来说可以正常工作。
英文:
You can simply "name" the two "Stores" differently in your struct. When you do not name an embedded struct field in a struct, it defaults to the name of the Embedded Struct, so, here, you have two fields named "Store", but you can easily make the name explicit. so go with this:
package main
import (
"file"
"fmt"
"sql"
)
type Datastore struct {
sqlStore *sql.Store
fileStore *file.Store
}
func main() {
ds := Datastore{&sql.Store{SqlStoreName: "MySQLStore"}, &file.Store{FileStoreName: "MyFileStore"}}
fmt.Println(ds.sqlStore.SqlStoreName, ds.fileStore.FileStoreName)
}
This works fine for me.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论