go語言學習筆記

Go語言之Mysql

package main

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

func main()  {
   //經過mysql驅動鏈接mysql
   db, err := sql.Open("mysql", "root:111111@tcp(127.0.0.1:3306)/test?charset=utf8")
   if err != nil{
      panic(err)
   }
   //一、插入操做
   stmt1, _ := db.Prepare("insert user_info set username=?,departname=?,createtime=?")
   res1, _ := stmt1.Exec("zhangsan","市場部","2019-2-1")
   id1, _ := res1.LastInsertId()
   fmt.Println(id1)
   //二、更新操做
   stmt2, _ := db.Prepare("update user_info set username=? where id=?")
   res2, _ := stmt2.Exec("lisi",10)
   affected, _ := res2.RowsAffected()
   fmt.Println(affected)
   //三、查詢操做
   rows, _ := db.Query("select * from user_info")
   for rows.Next(){
      var id int
      var username string
      var department string
      var createtime string
      err = rows.Scan(&id,&username,&department,&createtime)
      fmt.Println(id,username,department,createtime)
   }
   //四、刪除操做
   stmt3, _ := db.Prepare("delete from user_info where id=?")
   info, _ := stmt3.Exec(10)
   fmt.Println(info)
}

Go語言之聊天室

一、服務端代碼
/**
 * Description: 聊天室服務端
 */

package main

import (
   "net"
   "fmt"
   "strings"
   "os"
   "log"
)

var onlineConns = make(map[string]net.Conn)
var messageQueue = make(chan string, 1000)
var quitChan = make(chan bool)
var logFile *os.File
var logger *log.Logger

func CheckError(err error)  {
   if err != nil {
      panic(err)
   }
}

const (
   LOG_DIRECTORY = "./test.log"
)

func main()  {
   logFile,err := os.OpenFile(LOG_DIRECTORY, os.O_RDWR | os.O_CREATE, 0)
   if err != nil {
      fmt.Println("log file has created")
      os.Exit(-1)
   }
   defer logFile.Close()

   logger = log.New(logFile, "\r\n", log.Ldate|log.Ltime|log.Llongfile)

   listen_socket, err := net.Listen("tcp","127.0.0.1:8080")
   CheckError(err)
   defer listen_socket.Close()

   fmt.Println("service is waiting...")

   logger.Println("I am writing the logs...")

   go consumerMessage()

   for {
      conn, err := listen_socket.Accept()
      CheckError(err)
      //將conn存儲到onlineConns映射表
      addr := fmt.Sprintf("%s",conn.RemoteAddr())
      onlineConns[addr] = conn

      for ip := range onlineConns{
         fmt.Print(ip)
      }
      go ProcessInfo(conn)
   }
}

func consumerMessage()  {
   for {
      select {
      case message := <- messageQueue :
         //對消息進行解析
         doProcessMessage(message)
      case <- quitChan :
         break
      }
   }
}

func doProcessMessage(message string)  {
   contents := strings.Split(message,"#")
   if len(contents) > 1 {
      addr := contents[0]
      addr = strings.Trim(addr," ")
      sendMessage := strings.Join(contents[1:],"#")
      if conn, ok := onlineConns[addr]; ok {
         _, err := conn.Write([]byte(sendMessage))
         if err != nil {
            fmt.Println("online conns send failure")
         }
      }
   }else {
      contents := strings.Split(message,"*")
      if strings.ToUpper(contents[1]) == "LIST" {
         var ips string = ""
         for i := range onlineConns {
            ips = ips + "|" + i
         }
         if conn, ok := onlineConns[contents[0]]; ok {
            _, err := conn.Write([]byte(ips))
            if err != nil {
               fmt.Println("online conns send failure")
            }
         }
      }
   }
}

func ProcessInfo(conn net.Conn)  {
   buf := make([]byte, 1024)
   defer func(conn net.Conn) {
      addr := fmt.Sprintf("%s",conn.RemoteAddr())
      delete(onlineConns,addr)
      conn.Close()
      for i := range onlineConns{
         fmt.Println("now online conns:" + i)
      }
   }(conn)

   for {
      numofBytes, err := conn.Read(buf)
      if err != nil {
         break
      }
      if numofBytes != 0 {
         message := string(buf[:numofBytes])
         messageQueue <- message
         //remoteAddr := conn.RemoteAddr()
         //fmt.Println(remoteAddr)
         //fmt.Printf("Has received this message: %s\n", string(buf[:numofBytes]))
      }
   }
}
二、客戶端代碼
/**
 * Description: 聊天室客戶端
 */

package main

import (
   "net"
   "fmt"
   "bufio"
   "os"
   "strings"
)

func CheckError(err error)  {
   if err != nil {
      panic(err)
   }
}

func messageSend(conn net.Conn)  {
   var input string
   for {
      reader := bufio.NewReader(os.Stdin)
      data, _, _ := reader.ReadLine()
      input = string(data)

      if strings.ToUpper(input) == "EXIT" {
         conn.Close()
         break
      }

      _, err := conn.Write([]byte(input))
      if err != nil {
         conn.Close()
         fmt.Println("client connection failure:" + err.Error())
         break
      }
   }
}

func main()  {
   conn, err := net.Dial("tcp","127.0.0.1:8080")
   CheckError(err)
   defer conn.Close()

   //conn.Write([]byte("hell world"))
   go messageSend(conn)

   buf := make([]byte, 1024)
   for {
      length, err := conn.Read(buf)
      if err != nil {
         fmt.Println("您已經退出")
         os.Exit(0)
      }
      if length != 0 {
         fmt.Println("Has received server message:" + string(buf))
      }
   }
   fmt.Println("Client program end!")
}

變量逃逸-Escape Analysis

    go語言編譯機制:自動決定變量分配方式,提升運行效率mysql

    Go語言編程時,Go語言的設計者不但願開發者將精力放在內存應該分配在棧仍是堆上的問題。編譯器會自動幫助開發者完成這個糾結的選擇。但變量逃逸分析也是須要了解的一個編譯器技術。git

    關於棧堆進行內存分配,Go語言將這個過程整合到編譯器,命名爲「變量逃逸分析」,這個技術由編譯器分析代碼的特徵和代碼生命期,決定應該如何堆仍是棧進行內存分配,即便程序員使用Go完成了整個工程後也不會感覺到這個過程程序員

    1.逃逸分析

package main

import "fmt"

//逃逸分析
//變量c整形,值經過dummy()的返回值逃出函數
//c變量值被複制並做爲函數dummy的返回值返回

func main()  {
   var a int
   void()
   fmt.Println(a,dummy(0))
}

func void()  {

}

func dummy(b int) int {
   var c int
   c = b
   return c
}

go run -gcflags "-m -l" escape1.go 
# command-line-arguments
./escape1.go:8:13: a escapes to heap
./escape1.go:8:21: dummy(0) escapes to heap
./escape1.go:8:13: main ... argument does not escape
0 0github

    二、取地址發生逃逸

package main

import "fmt"

type Data struct {

}

func main()  {
   fmt.Println(dummys())
}

func dummys() *Data {
   var c  = Data{}
   return &c
}

go run -gcflags "-m -l" escape2.go 
# command-line-arguments
./escape2.go:15:9: &c escapes to heap
./escape2.go:14:6: moved to heap: c
./escape2.go:10:20: dummys() escapes to heap
./escape2.go:10:13: main ... argument does not escape
&{}sql

相關文章
相關標籤/搜索