如何在Golang中使用结构体指针

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

how to use struct pointers in golang

问题

我正在尝试使用gin进行简单的golang post和get请求,除了应该在结构变量中的值为空的部分之外,其他一切都正常。如果我没有解释清楚,下面是示例。

我的代码(主要部分):

package main

import (
	"github.com/cosimmichael/assessment/app/db_client"
	"github.com/cosimmichael/assessment/app/controllers"
	"github.com/gin-gonic/gin"
)

func main(){
	db_client.InitialiseDBConnection()

	r := gin.Default()

	r.POST("api/v1/products/create", controller.CreateProducts)
	r.GET("api/v1/products/{product_id}/show", controller.GetPosts)

	if err := r.Run(":3000"); err != nil {
		panic(err.Error())
	}
}

我的代码(控制器部分):

package controller

import (
	"net/http"
	"github.com/gin-gonic/gin"
	"github.com/cosimmichael/assessment/app/db_client"
)

type Post struct {
	id          int64    `json:"id"`
	title       *string  `json:"title"`
	description *string  `json:"description"`
}

func CreateProducts(c *gin.Context) {
	var reqBody Post
	if err := c.ShouldBindJSON(&reqBody); err != nil {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"error":   true,
			"message": "Invalid request body",
		})
		return
	}

	res, err := db_client.DBClient.Exec("INSERT INTO products (title, description) VALUES (?, ?);",
		reqBody.title,
		reqBody.description,
	)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":   true,
			"message": "Invalid request body",
		})
		return
	}

	id, err := res.LastInsertId()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error":   true,
			"message": "Invalid request body",
		})
		return
	}

	c.JSON(http.StatusCreated, gin.H{
		"error": false,
		"id":    id,
	})
}

func GetPosts(c *gin.Context){
	var posts []Post

	rows, err := db_client.DBClient.Query("SELECT id, title, description FROM products;")
	if err != nil {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"error":   true,
			"message": "Invalid request body",
		})
		return
	}

	for rows.Next(){
		var singlePost Post
		if err := rows.Scan(&singlePost.id, &singlePost.title, &singlePost.description); err != nil {
			c.JSON(http.StatusUnprocessableEntity, gin.H{
				"error":   true,
				"message": "Invalid request body",
			})
			return
		}
		posts = append(posts, singlePost)
	}

	c.JSON(http.StatusOK, rows)
}

我的代码(数据库客户端部分):

package db_client

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

var DBClient *sql.DB

func InitialiseDBConnection(){
	db, err := sql.Open("mysql","root:2580@tcp(localhost:3306)/grabit?parseTime=true")
	if err != nil {
		panic(err.Error())
	}
	err = db.Ping()
	if err != nil {
		panic(err.Error())
	}

	DBClient = db
}

现在,当我使用Postman插入新行时,它会插入一个只有id的空行,没有标题或描述。当我尝试获取数据时,我得到一个空数组。请问问题出在哪里?我对golang还不熟悉。

英文:

I am trying to do a simple golang with gin post and get request, every other thing works just fine, apart from the part that the values that are supposed to be in the struct variables are empty, the example is bellow if i didnt explain well
my code(main)

package main
import (
//"fmt"
"github.com/cosimmichael/assessment/app/db_client"
"github.com/cosimmichael/assessment/app/controllers"
"github.com/gin-gonic/gin"
// you need to import go mod  init for this parkage to work
// "github.com/cosimmichael/assessment/app/strutil"
// "github.com/cosimmichael/assessment/app/routers"
// "net/http"
)
func main(){
db_client.InitialiseDBConnection()
r := gin.Default()
r.POST("api/v1/products/create", controller.CreateProducts)
r.GET("api/v1/products/{product_id}/show", controller.GetPosts)
if err := r.Run(":3000"); err != nil {
panic(err.Error())
}
// router.HandleRoutes()
// fmt.Println("Server Starting.. @ port :3000")
// http.ListenAndServe(":3000", nil)
}

my code (controller)

package controller
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/cosimmichael/assessment/app/db_client"
// "fmt"
)
type Post struct {
id int64 			`json: "id"`
title *string 		`json: "title"`
description *string 	`json: "description"`
}
func CreateProducts(c *gin.Context) {
var reqBody Post
if err := c.ShouldBindJSON(&reqBody); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"error": true,
"message": "Invalid request body",
})
return
}
res, err := db_client.DBClient.Exec("INSERT INTO products (title, description) VALUES (?, ?);", 
reqBody.title,//"testing",
reqBody.description,//"Just testing something",
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": true,
"message": "Invalid request body2",
})
return
}
id, err := res.LastInsertId()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": true,
"message": "Invalid request body3",
})
return
}
c.JSON(http.StatusCreated, gin.H{
"error": false,
"id": id,
})
}
func GetPosts(c *gin.Context){
var posts []Post
rows, err := db_client.DBClient.Query("SELECT id, title, description FROM products;")
if err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"error": true,
"message": "Invalid request body",
})
return
}
for rows.Next(){
var singlePost Post
if err := rows.Scan(&singlePost.id, &singlePost.title, &singlePost.description); err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"error": true,
"message": "Invalid request body",
})
return
}
posts = append(posts, singlePost)
}
c.JSON(http.StatusOK, rows)
}

my code db_client

package db_client
import (
"database/sql"
//"time"
_ "github.com/go-sql-driver/mysql"
)
var DBClient *sql.DB
func InitialiseDBConnection(){
//[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
db, err := sql.Open("mysql","root:2580@tcp(localhost:3306)/grabit?parseTime=true")
if err != nil {
panic(err.Error())
}
err = db.Ping()
if err != nil {
panic(err.Error())
}
DBClient = db
}

now when I use postman insert new row, it inserts an empty row with only id, no title nor description, when i try fetching, i get an empty array, please what is the problem, i am new to golang

答案1

得分: 1

你需要将结构字段内的值的首字母大写。

例如:

type Book struct {
  ID     uint   `json:"id" gorm:"primary_key"`
  Title  string `json:"title"`
  Author string `json:"author"`
}
英文:

you need to capitalise the first character of values inside struct field.

For Example:

type Book struct {
ID     uint   `json:"id" gorm:"primary_key"`
Title  string `json:"title"`
Author string `json:"author"`
}

答案2

得分: 1

需要使用大写字母,因为如果不使用大写字母,只能在同一个包中看到。

大写字母 = 在所有包中可见

小写字母 = 只在同一个包中可见(例如:控制器只在这里可见)

英文:

Need to use a capitalise letter because if you don't use it you can only see in the same package.

Capitalise letter = see in all package

Normal letter = see only in same package (for example: controller only here)

答案3

得分: 1

使用结构体

如果字段或方法的名称以大写字母开头,该成员将被导出,并可以在包外访问。

如果字段或方法以小写字母开头,该成员将未导出,并且无法在包外访问。

注意:为了在Go语言的json包中执行诸如编组、解组等操作,字段名称必须以大写字母开头。因为它在内部使用反射进行处理。

英文:

Using Structs

If a field or method name starts with a capital letter, the member is exported and is accessible outside of the package.

If a field or method starts with a lowercase letter, the member is unexported and does not have accessibility outside of the package.

Note: The Inorder to do the operations like Marshalling Un-marshalling etc in golang json package you need to have field names should start with uppercase letters. Because it uses reflection inside to process.

huangapple
  • 本文由 发表于 2021年6月3日 15:51:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/67817505.html
匿名

发表评论

匿名网友

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

确定