



安装Golang

rm -rf usr/local/go && tar -C usr/local -xzf go1.16.2.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version


环境变量设置
Golang有一个环境变量GOPATH,这个变量表示第三方依赖包在本地的位置,大家指定一个方便访问的路径即可。
IDE推荐
推荐GoLand,功能强大,开箱即用,还有完善的插件生态。习惯用vim在linux下编程的同学也请留步,GoLand可以非常方便的安装vim插件,可以同时享受IDE的强大功能和vim高效的编辑能力。
Goland是付费软件,一般公司会提供正版给员工,如果还在学校且经济条件有限,大家可以先选30天的体验版,到30天卸载了重装

。


包的概念
package mainimport "fmt"func main() {fmt.Println("niuniumart")}

go build main.go 得到二进制文件main./main //执行代码
变量定义及初始化
package mainimport "fmt"var globalStr stringvar globalInt intfunc main() {var localStr stringvar localInt intlocalStr = "first local"localInt = 2021globalInt = 1024globalStr = "first global"fmt.Printf("globalStr is %s\n", globalStr) //globalStr is first globalfmt.Printf("globalStr is %d\n", globalInt) //globalStr is 1024fmt.Printf("localInt is %s\n", localStr) //localInt is first localfmt.Printf("localInt int is %d\n", localInt) //localInt int is 2021}

package mainimport "fmt"func main() {//数组初始化var strAry = [10]string{"aa", "bb", "cc", "dd", "ee"}//切片初始化var sliceAry = make([]string, 0)sliceAry = strAry[1:3]//字典初始化var dic = map[string]int{"apple":1,"watermelon":2,}fmt.Printf("strAry %+v\n", strAry)fmt.Printf("sliceAry %+v\n", sliceAry)fmt.Printf("dic %+v\n", dic)}

条件选择语法
package mainimport "fmt"func main() {localStr := "case3" //是的,还可以通过 := 这种方式直接初始化基础变量if localStr == "case3" {fmt.Printf("into ture logic\n")} else {fmt.Printf("into false logic\n")}//字典初始化var dic = map[string]int{"apple": 1,"watermelon": 2,}if num, ok := dic["orange"]; ok {fmt.Printf("orange num %d\n", num)}if num, ok := dic["watermelon"]; ok {fmt.Printf("watermelon num %d\n", num)}switch localStr {case "case1":fmt.Println("case1")case "case2":fmt.Println("case2")case "case3":fmt.Println("case3")default:fmt.Println("default")}}

循环写法
package mainimport "fmt"func main() {for i := 0; i < 5; i++ {fmt.Printf("current i %d\n", i)}j := 0for {if j == 5 {break}fmt.Printf("current j %d\n", j)j++}var strAry = []string{"aa", "bb", "cc", "dd", "ee"} //是的,不指定初始个数也ok//切片初始化var sliceAry = make([]string, 0)sliceAry = strAry[1:3]for i, str := range sliceAry {fmt.Printf("slice i %d, str %s\n", i, str)}//字典初始化var dic = map[string]int{"apple": 1,"watermelon": 2,}for k, v := range dic {fmt.Printf("key %s, value %d\n", k, v)}}
输出结果


协程(goroutine)
package mainimport ("fmt""time")func a() {time.Sleep(3 * time.Second)fmt.Println("it's a")}func b() {time.Sleep(2 * time.Second)fmt.Println("it's b")}func c() {time.Sleep(1 * time.Second)fmt.Println("it's c")}func main() {a()b()c()time.Sleep(1 * time.Second)}

package mainimport ("fmt""time")func a() {time.Sleep(3 * time.Second)fmt.Println("it's a")}func b() {time.Sleep(2 * time.Second)fmt.Println("it's b")}func c() {time.Sleep(1 * time.Second)fmt.Println("it's c")}func main() {go a()go b()go c()time.Sleep(5 * time.Second)}

通道(channel)
var ch0 chan intvar ch1 chan stringvar ch2 chan map[string]stringtype stu struct{}var ch3 chan stuvar ch4 chan *stu
package mainimport ("fmt""time")var ch chan intfunc a() {time.Sleep(3 * time.Second)a := 5ch <- afmt.Println("out of a")}func b() {time.Sleep(1 * time.Second)fromA := <- chb := fromA + 3fmt.Println("b is ", b)}func main() {ch = make(chan int, 1)go a()go b()time.Sleep(20 * time.Second)fmt.Println("out of main")}

chSync := make(chan int) //无缓冲chAsyn := make(chan int,1) //有缓冲
package mainimport ("fmt""time")var ch chan intfunc a() {time.Sleep(3 * time.Second)a := 5ch <- afmt.Println("out of a")}func b() {time.Sleep(1 * time.Second)}func main() {ch = make(chan int) //无缓冲管道go a()go b()time.Sleep(20 * time.Second)fmt.Println("out of main")}

package mainimport ("fmt""time")var ch chan intfunc a() {time.Sleep(3 * time.Second)a := 5ch <- afmt.Println("out of a")}func b() {time.Sleep(1 * time.Second)}func main() {ch = make(chan int, 1)go a()go b()time.Sleep(20 * time.Second)fmt.Println("out of main")}

接口( interface)
Go 语言提供了一种特别的数据类型——接口,它把所有具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
话不多说,看看🌰:
package mainimport "fmt"type Shape interface {Area() float64Perimeter() float64}// type recttype Rect struct {height float64weight float64}func (p *Rect) Area() float64 {return p.height * p.weight}func (p *Rect) Perimeter() float64 {return 2 * (p.height + p.weight)}func main() {var s Shape = &Rect{height:10, weight:8}fmt.Println(s.Area())fmt.Println(s.Perimeter())}

答案就是C++或者Java是需要主动声明基础类,而Golang,只需要实现某个interface的全部方法,那么就是实现了该类型。所以,Golang的继承关系是非侵入式的,这也是Golang的特色与优点。


函数覆盖率:被调用到的函数个数/总函数个数,通常要求100%; 行覆盖率:被调用到的行数/总行数,通常要求>60%。
牛牛之前在字节跳动SaaS化部门,没有专门的测试人员,对单元测试的要求就非常高,行覆盖率需要达到80%。
go test
go的test一般以xxx_test.go为文件名,xxx并没有特别要求必须是要实测的文件名; TestMain作为初始化test; Testxxx(t* testing.T); go test即可运行单元测试; go test --v fileName --test.run funcName可以指定单测某个方法。
├── main.go├── main_test.gopackage mainimport ("testing")func TestRect(t *testing.T) {var s Shape = &Rect{height:10, weight:8}if s.Area() != 80 {t.Errorf("area %f\n", s.Area())}if s.Perimeter() != 30 {t.Errorf("perimeter %f\n", s.Perimeter())}}

go convey
var (ShouldEqual = assertions.ShouldEqualShouldNotEqual = assertions.ShouldNotEqualShouldBeGreaterThan = assertions.ShouldBeGreaterThanShouldBeGreaterThanOrEqualTo = assertions.ShouldBeGreaterThanOrEqualToShouldBeLessThan = assertions.ShouldBeLessThanShouldBeLessThanOrEqualTo = assertions.ShouldBeLessThanOrEqualToShouldBeBetween = assertions.ShouldBeBetweenShouldNotBeBetween = assertions.ShouldNotBeBetweenShouldBeBetweenOrEqual = assertions.ShouldBeBetweenOrEqualShouldNotBeBetweenOrEqual = assertions.ShouldNotBeBetweenOrEqualShouldContainSubstring = assertions.ShouldContainSubstringShouldNotContainSubstring = assertions.ShouldNotContainSubstringShouldPanic = assertions.ShouldPanicShouldBeError = assertions.ShouldBeError)
package mainimport ("testing""github.com/smartystreets/goconvey/convey")func TestRect(t *testing.T) {convey.Convey("TestRect", t, func() {var s Shape = &Rect{height: 10, weight: 8}convey.So(s.Area(), convey.ShouldEqual, 80)convey.So(s.Perimeter(), convey.ShouldEqual, 30)})}

输出结果


什么是ORM?
package mainimport ("fmt""github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/mysql")type User struct {Name stringAge int}func main() {username := ""pwd := ""addr := "" //ip:portdatabase := ""args := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local", username, pwd, addr, database)// step1 : 连接数据库db, err := gorm.Open("mysql", args)if err != nil {fmt.Println(err)//do somethingreturn}defer db.Close()// step2 : 插入一行记录user := User{Name: "niuniu", Age: 18}err = db.Create(&user)if err != nil {fmt.Println(err)return}// step3 :查询记录var tmpUser Usererr = db.Where("name = ?", "niuniu").First(&tmpUser).Error //查询User并将信息保存到tmpUserif err != nil {fmt.Println(err)return}fmt.Println(tmpUser)}

输出结果


最简化样例
package mainimport ("log""net/http")func SayHello(w http.ResponseWriter, r *http.Request) {w.Write([]byte("hello")) //以字符串"hello"作为返回包}func main() {http.HandleFunc("/say_hello", SayHello)err := http.ListenAndServe(":8080", nil) //开启一个http服务if err != nil {log.Print("ListenAndServe: ", err)return}}
用框架来一发
package mainimport ("github.com/gin-gonic/gin""log""net/http")func SayHello(c *gin.Context) {c.String(http.StatusOK, "hello") //以字符串"hello"作为返回包}func main() {engine := gin.Default() //生成一个默认的gin引擎engine.Handle(http.MethodGet,"/say_hello", SayHello)err := engine.Run(":8080") //使用8080端口号,开启一个web服务if err != nil {log.Print("engine run err: ", err.Error())return}}








文章转载自牛牛码特,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





