如何在结构体内声明类似空对象/结构体的内容?

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

How to declare something like empty Object/Struct inside Struct?

问题

你好!你想要创建一个空的对象/结构体作为领域模型数据类型,对吗?你正在使用Fiber作为你的框架,并且想要从Go语言的响应API中获取类似以下示例的结果:

{
  "success": true,
  "message": "Success registered",
  "data": {
    "first_name": "asdfa",
    "last_name": "asdfa",
    "email": "fadsfa",
    "password": "asdfasfas"
  }
}

你尝试的方式是在ResponseDto结构体中使用fiber.Map作为Data字段的类型。然后在控制器中创建一个fiber.Map对象,并将其赋值给Data字段。但是你发现返回的响应中有嵌套的数据,而你希望它只有一层嵌套,就像你的示例一样。你想知道如何实现这一点,应该使用什么数据类型,并如何赋值。

要实现你的需求,你可以使用一个自定义的结构体类型作为Data字段的类型,而不是使用fiber.Map。这样可以确保只有一层嵌套的数据结构。以下是一个可能的解决方案:

首先,创建一个名为UserData的结构体,用于存储用户数据:

type UserData struct {
    FirstName string `json:"first_name"`
    LastName  string `json:"last_name"`
    Email     string `json:"email"`
    Password  string `json:"password"`
}

然后,在ResponseDto结构体中将Data字段的类型更改为UserData

type ResponseDto struct {
    Success bool     `json:"success"`
    Message string   `json:"message"`
    Data    UserData `json:"data"`
}

接下来,在控制器中创建一个UserData对象,并将其赋值给Data字段:

func Register(c *fiber.Ctx) error {
    user := request.UserRequest{}
    // 做一些操作然后返回

    userData := UserData{
        FirstName: user.FirstName,
        LastName:  user.LastName,
        Email:     user.Email,
        Password:  user.Password,
    }

    return c.JSON(models.ResponseDto{
        Success: false,
        Message: "Success registered",
        Data:    userData,
    })
}

这样,你将得到一个只有一层嵌套的响应,就像你的示例所示。希望这可以帮助到你!如果你还有其他问题,请随时问我。

英文:

Hi i am process of learning the Go language, and i want to ask how to create empty Object/Struct as domain model data type? i am using Fiber as my framework and here is the example of what i want to get from golang response api is something like this :

{
  "success": true,
  "message": "Success registered",
  "data": {
      "first_name": "asdfa",
      "last_name": "asdfa",
      "email": "fadsfa",
      "password": "asdfasfas"
  }
}

and here is how i try, here is my responseDto.go :

type ResponseDto struct {
	Success bool   `json:"success"`
	Message string   `json:"message"`
	Data    fiber.Map `json:"data"`
}

then here is how my controller looked like :

func Register(c *fiber.Ctx) error {
	user := request.UserRequest{}
    //do something then return

	return c.JSON(models.ResponseDto{
		Success: false,
		Message: "Success registered",
		Data: fiber.Map{
			"data": user,
		},
	})
}

then here is the response :

{
  "success": false,
  "message": "Success registered",
  "data": {
    "data": {
      "first_name": "asdfa",
      "last_name": "asdfa",
      "email": "fadsfa",
      "password": "asdfasfas"
    }
  }
}

as you can see, i will have nested data, but i don't want it to be nested, i want it just one level nested, like my example . How can i achieve it? what data type should i use and how to use it to assign the value?

答案1

得分: 2

你需要将"user"转换为fiber.Map类型。

func Register(c *fiber.Ctx) error {
   user := request.UserRequest{}
   //做一些操作然后返回

   return c.JSON(models.ResponseDto{
       Success: false,
       Message: "Success registered",
       Data: fiber.Map{
           "user_name": user.Name,
           "user_age": user.Age,
       },
   })
}

或者你可以修改ResponseDto结构体:

type ResponseDto struct {
   Success bool   `json:"success"`
   Message string   `json:"message"`
   Data    fiber.Map `json:"data"`
}
英文:

You have to "convert" user to fiber.Map

func Register(c *fiber.Ctx) error {
   user := request.UserRequest{}
   //do something then return

   return c.JSON(models.ResponseDto{
       Success: false,
       Message: "Success registered",
       Data: fiber.Map{
           "user_name": user.Name,
           "user_age": user.Age,
       },
   })
}

Or you can change ResponseDto

type ResponseDto struct {
   Success bool   `json:"success"`
   Message string   `json:"message"`
   Data    request.UserRequest `json:"data"`
}

答案2

得分: 1

如果您不想要嵌套数据,请不要嵌套它。如果这听起来像一个重言,我很抱歉,但我不确定如何解决这个问题。

具体来说:如果datarequest.UserRequest类型,请将其作为结构字段添加:

type ResponseDto struct {
    Success bool                `json:"success"`
    Message string              `json:"message"`
    Data    request.UserRequest `json:"data"`
}

但是,这会将您的请求和响应模型耦合在一起。如果您想避免这种情况(我也想避免),您必须接受一些更冗长的代码,并逐个设置fiber.Map条目。不,您不能迭代结构字段。您可以通过定义一个专用类型使您的代码更具表达性:

type UserMap fiber.Map

type ResponseDto struct {
    Success bool    `json:"success"`
    Message string  `json:"message"`
    Data    UserMap `json:"data"`
}

resp := ResponseDto{
    Success: false,
    Message: "Success registered",
    Data: UserMap{
        "first_name": user.FirstName,
        // ...以此类推
    },
}
英文:

If you don't want nested data, don't nest it. Sorry if this sounds like a tautology, but I'm not sure how else to address it.

Concretely: if the data is a request.UserRequest, add that as struct field:

type ResponseDto struct {
    Success bool                `json:"success"`
    Message string              `json:"message"`
    Data    request.UserRequest `json:"data"`
}

But that couples your request and response models. If you want to avoid that (I would want to), you must put up with having some more verbose code and set the fiber.Map entries one by one. No, you can't iterate over struct fields. You can make your code somewhat more expressive by defining a dedicated type:

type UserMap fiber.Map

type ResponseDto struct {
    Success bool    `json:"success"`
    Message string  `json:"message"`
    Data    UserMap `json:"data"`
}

resp := ResponseDto{
    Success: false,
    Message: "Success registered",
    Data: UserMap{
        "first_name": user.FirstName,
        // ...and so on
    },
}

huangapple
  • 本文由 发表于 2021年7月20日 18:02:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/68452996.html
匿名

发表评论

匿名网友

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

确定