Golang中的类型详解
Golang中的类型详解 大家好!我是Go语言的新手,正在尝试使用Fiber和MGM(MongoDB)构建一个简单的REST API。 我想了解变量是如何传递的。请看下面的函数…
func CreateTodo(ctx *fiber.Ctx) {
params := new(struct {
Title string
Desc string
})
ctx.BodyParser(¶ms)
if len(params.Title) == 0 {
ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"ok": false,
"error": "Title not specified",
})
return
}
todo := models.CreateTodo(
params.Title,
params.Desc,
)
if err := mgm.Coll(todo).Create(todo); err != nil {
ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"ok": false,
"error": err.Error(),
})
return
}
ctx.JSON(fiber.Map{
"ok": true,
"todo": todo,
})
}
重点关注这几行…
todo := models.CreateTodo(
params.Title,
params.Desc,
)
if err := mgm.Coll(todo).Create(todo); err != nil {
为什么大多数人不像下面这样写:
if err := mgm.Coll(&models.Todo{}).Create(todo); err != nil {
既然这样是有效的?我的理解是 mgm.Coll 需要集合的“结构”来查找。
另外,为什么 if err := mgm.Coll(models.Todo).Create(todo); err != nil { 是无效的?难道类型本身不足以让函数确定结构吗?为什么我们需要用 &models.Todo{} 创建一个新实例?
更多关于Golang中的类型详解的实战教程也可以访问 https://www.itying.com/category-94-b0.html
额外信息如下:
type Todo struct {
mgm.DefaultModel `bson:",inline"`
Title string `json:"title" bson:"title"`
Desc string `json:"desc" bson:"desc"`
Done bool `json:"done" bson:"done"`
}
func CreateTodo(title, desc string) *Todo {
return &Todo{
Title: title,
Desc: desc,
Done: false,
}
}
aceix:
既然
if err := mgm.Coll(&models.Todo{}).Create(todo); err != nil {是有效的,为什么大多数人不这么写呢?我的理解是mgm.Coll需要集合的“结构”来查找。
这类似于变量的“显式类型声明”与“类型推断”之间的区别:显式类型声明明确地定义了每个变量的类型(例如 var todo *Todo = CreateTodo("title", "description")),而类型推断允许你只写 var todo = CreateTodo("title", "description") 或者更常见的是 todo := CreateTodo("title", "description"))。
有些人喜欢显式类型,因为每个表达式结果的类型都写在你面前,无需去查找每个函数返回什么。就我个人而言,我讨厌显式类型声明,我会选择 mgm.Coll(todo) 而不是 mgm.Coll(&models.Todo{})。如果我们想把 Todo 重命名为 ToDo 怎么办?你必须手动或用工具替换每一个出现的地方。如果将来 Todo 扩展了,出现了 DependentTodo 和/或 ExternalTodo 等类型,导致 CreateTodo 被改为返回一个接口怎么办?现在 mgm.Coll(&models.Todo{}) 会得到错误的类型,但如果你写 mgm.Coll(todo),类型推断就会选择正确的集合。
aceix:
另外,为什么
if err := mgm.Coll(models.Todo).Create(todo); err != nil {是无效的?难道类型本身不足以让函数确定结构吗?为什么我们要用&models.Todo{}创建一个新实例?
另一个好问题:有些编程语言允许值和类型都用作函数、其他类型等的参数(例如,在类C语言中,“值参数”通常用圆括号 ( ) 括起来,而“类型参数”通常用“尖括号” < > 括起来)。Go只允许值作为参数,但为了绕过这个限制,你确实可以使用反射。
在 mgm.Coll 内部,它可能会检查其参数的类型,并返回它已经为该类型保存的特定集合信息,或者,如果这是第一次为该类型的实例调用 mgm.Coll,它会根据其参数类型生成所需的任何特定集合信息。


