在结构体中嵌套两个具有相同名称的结构体。

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

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
}

Playground链接

请注意,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
}

Playground link.

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.

huangapple
  • 本文由 发表于 2017年1月31日 14:39:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/41951172.html
匿名

发表评论

匿名网友

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

确定