英文:
Golang: struct inside an interface?
问题
所以我有一个名为UserService
的接口,位于service
包中。
我有两个简单的结构体,表示HTTP调用的请求体和响应体。我还有另一个结构体实现了UserService
接口。
我想把这些结构体,称为UserResponse
和UserRequest
,放在接口中,这样其他服务就可以使用它们来进行HTTP调用。此外,请求和响应应该是可用的(struct UserResponse
,而不是struct userResponse
),以便代码的其他部分可以使用它们。
我在接口中定义了一个名为GetUser(request UserRequest) UserResponse
的函数。
然而,每当我引用UserRequest
时,我必须使用service.UserRequest
而不是service.UserService.UserRequest
。这很糟糕,因为我不希望与用户相关的对象进入服务命名空间。我希望每个服务相关的数据都在其自己的接口、文件等下进行组织。不幸的是,如果我把UserResponse
放在UserService
接口中,就会出错。所以我把它放在与UserService
同一级别的位置,这就是为什么它们显示为service.UserResponse
的原因。如何以service.UserService.UserResponse
的方式访问UserResponse
?
英文:
So I have an interface, called UserService
inside a package service
I have two simple structs representing the body and response of a HTTP call. I have another struct implementing the UserService
interface.
I want to put these structs, call them UserResponse
and UserRequest
inside the interface so other services can use them to make the HTTP call. Furthermore, the request and response should be available (struct UserReponse
, not struct userResponse
) so other parts of the code can use them.
I define a function in the interface called GetUser(request UserRequest) UserResponse
However, whenever I reference UserRequest
I have to use service.UserRequest
and not service.UserService.UserRequest
. This is bad because I don't want user-related objects to go into the service namespace. I want each service related data to organized under its own interface, file, etc. Unfortunately, I get an error if I put UserResponse
inside the UserService
interface. So I put it at the same level as UserService
, which is why they are showing up as service.UserResponse
. How do I go about accessing UserResponse
as service.UserService.UserResponse
?
答案1
得分: 5
这是一个关于如何以更“惯用”的Go方式组织代码的建议:
package user
type Request struct {
...
}
type Response struct {
...
}
type Service interface {
GetUser(r Request) Response
}
在user
包之外,代码将如下所示:
s := user.NewService()
var req user.Request
var resp user.Response
resp = s.GetUser(req)
如你所见,代码使用了更短的名称,但仍然非常易读。
像service
这样的包名表明你按层次而不是按功能组织代码。我不建议这样做。这里有一篇有趣的文章讨论了这个问题:http://www.javapractices.com/topic/TopicAction.do?Id=205。虽然它使用的是Java,但原则适用于任何编程语言。
英文:
Here is a suggestion to organize your code in more "idiomatic" Go way:
package user
type Request struct {
...
}
type Response struct {
...
}
type Service interface {
GetUser(r Request) Response
}
Outside of user
package the code will look like:
s := user.NewService()
var req user.Request
var resp user.Response
resp = s.GetUser(req)
As you can see the code uses much shorter names and still remains very readable.
Package names like service
shows that you organize the code in your app by layers instead of by features. I wouldn't recommend it. Here is interesting article about it: http://www.javapractices.com/topic/TopicAction.do?Id=205. It uses Java but the principle applies to any programming language.
答案2
得分: -1
Go不是Java,Go甚至不是C++。你应该将Go视为“带有接口的C”。
特别要注意的是,你不能按照你想要的方式操作,因为你不能在接口定义中嵌套结构体定义。请注意,你可以在结构体内部嵌套结构体,但你不能直接实例化嵌套的结构体。
你能做的最接近的方法是将每个逻辑对象组移动到自己的包中。
英文:
Go is not Java; Go is even not C++. You should think of Go as "C with interfaces".
In particular, you cannot do as you want, as you cannot nest struct definitions in interface definitions. Note that you can nest structs inside structs, but you cannot instantiate a nested struct directly.
The closest you can do is to move each logical group of objects to its own package.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论