Golang基础学习

Golang基础

参考:

  1. (1条消息) golang在windows平台使用zmq并使用官方文档实现通讯_qurmytywl的博客-CSDN博客
  2. Go 语言教程 | 菜鸟教程 (runoob.com)
  3. (1条消息) go操作mysql数据库_山河万里的博客-CSDN博客_go mysql 数据库
  4. Go语言之搭建文件下载服务端 - 腾讯云开发者社区-腾讯云 (tencent.com)
  5. Go语言的创建HTTP服务器_DXB2021的博客-CSDN博客_go http服务器
  6. go中使用protobuf

Windows搭建环境

  1. The Go Programming Language (google.cn)

基础语法

  1. 格式化输出

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var num = 123
    	var data = "2020-12-31"
    	var url = "Code=%d&endData=%s"
    	var targetUrl, _ = fmt.Printf(url, num, data)
    	fmt.Println(targetUrl)
    }
    
    • Golang使用var声明变量
    • 返回值中_表示错误结果
  2. 变量

    1. 基本数据类型

      var a int
      fmt.Println(a)
      //var a *int
      //var a []int
      //var a map[string] int
      //var a chan int
      //var a func(string) int
      //var a error // error 是接口
      intVal := 1 //声明并赋值
      fmt.Println(intVal)
      const (
          aa = iota //可以顺序自增的数
          b
          c = "ha"
          d
          e = iota
      )
      
    2. 数组&集合

      strings := []string{"google", "baidu"}
      map1 := make(map[int]float32)
      map1[1] = 1.0
      map1[2] = 2.0
      map1[3] = 3.0
      
  3. 控制语句

    if a < 20 {
    	fmt.Println("a小于20")
    } else if a == 20 {
    	fmt.Println("a等于20")
    } else {
    	fmt.Println("a大于20")
    }
    //switch不需要break
    //switch可以判断interface的类型
    var x interface{}
    switch x.(type) {
    case nil:
    	fmt.Println("x的类型是nil")
    case int:
    	fmt.Println("x的类型是int")
    default:
    	fmt.Println("未知型")
    }
    sum := 0
    for i := 0; i <= 10; i++ {
    	sum += i
    }
    for key, value := range map1 {
    	fmt.Println(key, value)
    }
    
  4. 函数&接口

    func max(num1, num2 int) int {
    	var result int
    	if num1 > num2 {
    		result = num1
    	} else {
    		result = num2
    	}
    	return result
    }
    
    func swap(x, y *int) {
    	var temp int
    	temp = *x
    	*x = *y
    	*y = temp
    	fmt.Println(*x, *y)
    }
    
    //函数指针类型
    type cb func(int) int
    
    func testcallback(x int, f cb) {
    	f(x)
    }
    
    /* 定义结构体 */
    type Circle struct {
    	radius float64
    }
    
    func (c Circle) getArea() float64 {
    	return c.radius * c.radius
    }
    
    // 注意如果想要更改成功c的值,这里需要传指针
    func (c *Circle) changeRadius(radius float64) {
    	c.radius = radius
    }
    
    // 以下操作将不生效
    //func (c Circle) changeRadius(radius float64)  {
    //   c.radius = radius
    //}
    // 引用类型要想改变值需要传指针
    func change(c *Circle, radius float64) {
    	c.radius = radius
    }
    
  5. 错误处理

    func Sqrt(f float64) (float64, error) {
        if f < 0 {
            return 0, errors.New("math: square root of negative number")
        }
        // 实现
    }
    result, err:= Sqrt(-1)
    
    if err != nil {
       fmt.Println(err)
    }
    
  6. 并发

    //线程
    func say(s string) {
            for i := 0; i < 5; i++ {
                    time.Sleep(100 * time.Millisecond)
                    fmt.Println(s)
            }
    }
    
    func main() {
            go say("world")
            say("hello")
    }
    
    func fibonacci(n int, c chan int) {
            x, y := 0, 1
            for i := 0; i < n; i++ {
                    c <- x
                    x, y = y, x+y
            }
            close(c)
    }
    //通道
    func main() {
            c := make(chan int, 10)
            go fibonacci(cap(c), c)
            // range 函数遍历每个从通道接收到的数据,因为 c 在发送完 10 个
            // 数据之后就关闭了通道,所以这里我们 range 函数在接收到 10 个数据
            // 之后就结束了。如果上面的 c 通道不关闭,那么 range 函数就不
            // 会结束,从而在接收第 11 个数据的时候就阻塞了。
            for i := range c {
                    fmt.Println(i)
            }
    }
    

混合编程

//main.go
package main

func main() {
	var a = 10
	var b = 10
	AddPrint(a, b)
}

//hello.go
package main

//int Add(int a, int b){
//	return a+b;
//}
import "C"
import "fmt"

func AddPrint(a int, b int) {
	fmt.Println(C.Add(C.int(a), C.int(b)))
}
  • 需要新建src文件夹
  • 需要保留go.mod
  • 需要安装gcc

Zmq的使用

  1. 环境搭建

    1. 对于经常可随便运行的项目,可以新建一个文件夹,名为main,方便启动多个main函数

    2. 对于正式的开发项目(只有一个main),创建文件夹名为src

    3. 使用vcpkg下载zmq,下载的x64-windows版本

      vcpkg install cppzmq --triplet=x64-windows
      
    4. 环境变量:

      GOPROXY=https://goproxy.cn;CGO_CFLAGS=-IC:/Users/20582/vcpkg-master/installed/x64-windows/include;CGO_LDFLAGS=-LC:/Users/20582/vcpkg-master/installed/x64-windows/lib -l:libzmq-mt-4_3_4.lib
      

      用于指定头文件、LIB库文件

  2. 客户端

    package main
    
    import (
    	"fmt"
    
    	zmq "github.com/pebbe/zmq4"
    )
    
    func main() {
    	zctx, _ := zmq.NewContext()
    
    	// Socket to talk to server
    	fmt.Printf("Connecting to the server...\n")
    	s, _ := zctx.NewSocket(zmq.REQ)
    	s.Connect("tcp://localhost:5555")
    
    	// Do 10 requests, waiting each time for a response
    	for i := 0; i < 10; i++ {
    		fmt.Printf("Sending request %d...\n", i)
    		s.Send("Hello", 0)
    
    		msg, _ := s.Recv(0)
    		fmt.Printf("Recieved reply %d [ %s ]\n", i, msg)
    	}
    }
    
    
  3. 服务器

    package main
    
    import (
    	"log"
    	"time"
    
    	zmq "github.com/pebbe/zmq4"
    )
    
    func main() {
    	zctx, _ := zmq.NewContext()
    
    	s, _ := zctx.NewSocket(zmq.REP)
    	s.Bind("tcp://*:5555")
    
    	for {
    		// Wait for next request from client
    		msg, _ := s.Recv(0)
    		log.Printf("Recieved %s\n", msg)
    
    		// Do some 'work'
    		time.Sleep(time.Second * 1)
    
    		// Send reply back to client
    		s.Send("World", 0)
    	}
    }
    
    
  4. protobuf的使用

    go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
    protoc --go_out=. *.proto
    也可以将所有的文件统计出来
    set proto_list=1.proto 2.proto
    protoc --go_out=. %proto_list%
    
    package main
    
    import (
    	"fmt"
    	"github.com/golang/protobuf/proto"
    	pb "mmo/demoTest/protobuffDemo/pb"
    )
    
    func main() {
    	//定义一个Person结构对象
    	person := &pb.Person{
        	Name:   "wuzi",
        	Age:    16,
        	Emails: []string{"sss@qq.com", "dsa15@qq.com"},
        	Phones: []*pb.PhoneNumber{
            	&pb.PhoneNumber{
                	Number: "131254222",
                	Type:   pb.PhoneType_MOBILE,
           	 },
            	&pb.PhoneNumber{
                	Number: "154512451",
                	Type:   pb.PhoneType_WORK,
            	},
        	},
    	}
    
    //将person对象,就是将protobuf中的message进行序列化,得到一个二进制
    //data就是传送的数据,对方需要按照Message Person格式进行解析
    p, err := proto.Marshal(person)
    if err != nil {
        fmt.Println("marshal err:", err)
    }
    fmt.Println("编码后的person:", p)
    
    //解码
    np := new(pb.Person)
    err = proto.Unmarshal(p, np)
    if err != nil {
        fmt.Println("unmarshal err:", err)
    }
    fmt.Println("解码后的person:", np)
    

}

```

HTTP/HTTPS请求

  1. GET/POST

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"log"
    	"net/http"
    )
    
    func helloWorld(w http.ResponseWriter, r *http.Request) {
    	if r.URL.Path != "/" {
    		http.NotFound(w, r)
    		return
    	}
    	switch r.Method {
    	case "GET":
    		for k, v := range r.URL.Query() {
    			fmt.Printf("%s:  %s\n", k, v)
    		}
    		w.Write([]byte("Received a GET request\n"))
    	case "POST":
    		reqBody, err := ioutil.ReadAll(r.Body)
    		if err != nil {
    			log.Fatal(err)
    		}
    		fmt.Printf("%s\n", reqBody)
    		w.Write([]byte("Received a POST request\n"))
    	default:
    		w.WriteHeader(http.StatusNotImplemented)
    		w.Write([]byte(http.StatusText(http.StatusNotImplemented)))
    	}
    
    }
    
    func main() {
    	http.HandleFunc("/", helloWorld)
    	http.ListenAndServe(":8000", nil)
    }
    
    curl -si "http://localhost:8000/?foo=1&bar=2"
    curl -si POST -d "some data to send" http://localhost:8000/
    
  2. 下载请求

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <a href="download?filename=abc.png">下载</a>
    </body>
    </html>
    
    package main
    
    import (
       "net/http"
       "html/template"
       "io/ioutil"
    )
    
    func showDownloadPage(rw http.ResponseWriter,r *http.Request){
       t,_:=template.ParseFiles("template/html/download.html")
       t.Execute(rw,nil)
    }
    func download(rw http.ResponseWriter,r *http.Request){
       //获取请求参数
       fn:=r.FormValue("filename")
       //设置响应头
       header:=rw.Header()
       header.Add("Content-Type","application/octet-stream")
       header.Add("Content-Disposition","attachment;filename="+fn)
       //使用ioutil包读取文件
       b,_:=ioutil.ReadFile("D:/"+fn)
       //写入到响应流中
       rw.Write(b)
    }
    
    func main() {
       server:=http.Server{Addr:"localhost:8899"}
    
       http.HandleFunc("/showdownload",showDownloadPage)
       http.HandleFunc("/download",download)
    
       server.ListenAndServe()
    }        
    

数据库操作

  1. 安装:https://dev.mysql.com/downloads/mysql/

  2. 查看:DBeaver

    mysqld --initialize --console
    mysqld -install
    net start mysql
    mysql -u root -p 前面的密码
    alter user 'root'@'localhost' identified by '想要设置的密码';
    commit;
    quit;
    
  3. 使用go操作

    package main
     
    import (
       "database/sql"
       "fmt"
     
       _ "github.com/go-sql-driver/mysql"
    )
     
    func errorHandler(err error) {
       if err != nil {
          fmt.Println(err.Error())
       }
    }
     
    var (
       CREATE_TABLE = "CREATE TABLE student(" +
          "sid INT(10) NOT NULL AUTO_INCREMENT," +
          "sname VARCHAR(64) NULL DEFAULT NULL," +
          "age INT(10) DEFAULT NULL,PRIMARY KEY (sid))" +
          "ENGINE=InnoDB DEFAULT CHARSET=utf8;"
    )
     
    // 建立数据库连接
    func setupConnect() *sql.DB {
       db, err := sql.Open("mysql", "root:xxxxxx@tcp(118.24.159.133:3306)/student?charset=utf8")
       errorHandler(err)
       return db
    }
     
    // 创建表
    func CreateTable(db *sql.DB, sql string) {
       _, err := db.Exec(sql)
       errorHandler(err)
    }
     
    var INSERT_DATA = `INSERT INTO student(sid,sname,age) VALUES(?,?,?);`
     
    // 插入数据
    func Insert(db *sql.DB) {
       db.Exec(INSERT_DATA, 1, "唐僧", 30)
    }
     
    var UPDATE_DATA = `UPDATE student SET age=28 WHERE sname="唐僧";`
     
    // 修改数据
    func Update(db *sql.DB) {
       db.Exec(UPDATE_DATA)
     
    }
     
    var DELETE_DATA = `DELETE FROM student WHERE age>=30`
     
    // 删除记录
    func Delete(db *sql.DB) {
       db.Exec(DELETE_DATA)
    }
     
    var DELETE_TABLE = `DROP TABLE student;`
     
    // 删除表
    func DeleteTable(db *sql.DB) {
       db.Exec(DELETE_TABLE)
    }
     
    var QUERY_DATA = `SELECT * FROM student;`
     
    // 查询数据
    func Query(db *sql.DB) {
       rows, err := db.Query(QUERY_DATA)
       if err != nil {
          fmt.Println(err)
       }
       for rows.Next() {
          var name string
          var id int
          var age int
          if err := rows.Scan(&id, &name, &age); err != nil {
             fmt.Println(err)
          }
          fmt.Printf("%s is %d\n", name, age)
       }
    }
     
    func main() {
       // 建立数据连接
       db := setupConnect()
       // 创建数据库表
       CreateTable(db, CREATE_TABLE)
       // 插入数据
       Insert(db)
       // 查询数据
       Query(db)
       // 删除数据
       Delete(db)
       // 插入数据
       Insert(db)
       // 修改数据
       Update(db)
       // 查询数据
       Query(db)
       // 删除表
       DeleteTable(db)
       // 关闭数据库连接
       db.Close()
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于上面的引用内容,golang基础语法学习可以参考以下几个步骤: 1. 首先,我们需要安装golang开发环境。你可以直接进入官网(https://go.dev/)下载并安装golang的解释器。 2. 接下来,我们可以开始学习golang的语法。从上面的引用内容可以看出,golang的语法和Java的结构很相似,所以如果你之前有Java编程的经验,可以借鉴一些类比来学习。但是即使你没有Java的经验,也不用担心,golang的语法相对简单并且易于学习。 3. 另外,golang被称为“云计算时代的开发利器”,在使用过程中给人一种优雅、亲切、舒适的感觉。因此,在学习golang的过程中,你可能会发现它的语法设计和使用方式非常人性化。 综上所述,学习golang基础语法可以通过安装开发环境、参考Java的结构以及体验其优雅、亲切、舒适的特点来进行。希望这些信息能够帮助你开始学习golang基础语法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [一文看完golang基础语法](https://blog.csdn.net/qq_35889508/article/details/128125279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值