Golang:接口中的结构体?

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

Golang: struct inside an interface?

问题

所以我有一个名为UserService的接口,位于service包中。

我有两个简单的结构体,表示HTTP调用的请求体和响应体。我还有另一个结构体实现了UserService接口。

我想把这些结构体,称为UserResponseUserRequest,放在接口中,这样其他服务就可以使用它们来进行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.

huangapple
  • 本文由 发表于 2015年8月12日 21:44:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/31967057.html
匿名

发表评论

匿名网友

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

确定