onvno / techcollect

IT博客文章收集
0 stars 0 forks source link

20190617 - Go语言相关 #3

Open onvno opened 5 years ago

onvno commented 5 years ago

升级

删除原版本,重新安装

  1. Uninstall the exisiting version As mentioned here, to update a go version you will first need to uninstall the original version.

To uninstall, delete the /usr/local/go directory by:

$ sudo rm -rf /usr/local/go
  1. Install the new version Go to the downloads page and download the binary release suitable for your system.

  2. Extract the archive file To extract the archive file:

    $ sudo tar -C /usr/local -xzf /home/nikhita/Downloads/go1.8.1.linux-amd64.tar.gz
  3. Make sure that your PATH contains /usr/local/go/bin

    $ echo $PATH | grep "/usr/local/go/bin"

How to update the Go version

onvno commented 5 years ago

workspace

之前已设置过

$GOPATH

需要看一下官方文档:https://golang.org/doc/code.html#Workspaces

onvno commented 5 years ago

web框架选择

beego 国产很成熟 Martini 很成熟 Macaron 类似 Martini,更自由 gin 用了都说好

https://www.zhihu.com/question/27370112

最终选择gin

onvno commented 5 years ago

Gin:https://gin-gonic.com/docs/examples/ascii-json/

onvno commented 5 years ago

连接数据库

教程:使用 go 的 gin 和 gorm 框架来构建 RESTful API 微服务

package main

import (
       "github.com/gin-gonic/gin"
       "github.com/jinzhu/gorm"
       _ "github.com/jinzhu/gorm/dialects/mysql"
)

var db *gorm.DB
func init() {
 //open a db connection
 var err error
 db, err = gorm.Open("mysql", "root:12345@/demo?charset=utf8&parseTime=True&loc=Local")
 if err != nil {
  panic("failed to connect database")
 }
//Migrate the schema
 db.AutoMigrate(&todoModel{})
}
onvno commented 5 years ago

go项目目录结构

目录

-wblog |-conf 配置文件目录 |-controllers 控制器目录 |-helpders 公共方法目录 |-models 数据库访问目录 |-static 静态资源目录 |-css css文件目录 |-images 图片目录 |-js js文件目录 |-libs js类库 |-system 系统配置文件加载目录 |-tests 测试目录 |-vendor 项目依赖其他开源项目目录 |-views 模板文件目录 |-main.go 程序执行入口



* 其他一些文章
[有读者反馈希望我写一点go-gin框架使用,我就结合我的项目略讲一二(自己也在学习中)。](https://juejin.im/post/5bfbbaa5e51d45315070d435)
[gin项目的经验](https://steak.page/2018/12/05/2018-12-01-gin-project-structure/)
onvno commented 5 years ago

依赖管理

onvno commented 5 years ago

Deploy

Deploy a Go Gin Web Server

onvno commented 5 years ago

Gin路由全介绍中文: Golang 微框架 Gin 简介 👍👍👍

onvno commented 5 years ago

go method

查询数据库用法是发现有些函数用法比较特殊:golang-gin-mysql-curd.go

func (p Person) get() (person Person, err error) {

    row := db.QueryRow("SELECT id, first_name, last_name FROM person WHERE id=?", p.Id)
    err = row.Scan(&person.Id, &person.FirstName, &person.LastName)
    if err != nil {
        return
    }
    return
}

Go中使用a.handleEvent类似的方法时,可以如下定义: Methods

package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := Vertex{3, 4}
    fmt.Println(v.Abs())
}
onvno commented 5 years ago

Go Tour学习一些整理

Pointers to structs

下边定义的p为指针,当获取值的时候,本来是需要访问(*p).X,但是略显麻烦,Go支持直接使用p.x:

package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    p := &v
    p.X = 2000
    fmt.Println(v)
}

数组Array

数组的长度也是数组的类型一部分,所以需要和类型在一起:

package main

import "fmt"

func main() {
    var a [2]string
    a[0] = "Hello"
    a[1] = "World"
    fmt.Println(a[0], a[1])
    fmt.Println(a)

    primes := [6]int{2, 3, 5, 7, 11, 13}
    fmt.Println(primes)
}

make创建slice

Creating a slice with make make用于初始化slice, map,channel?

b := make([]int, 0, 5) // len(b)=0, cap(b)=5,创建一个数组最多为空,默认为空
b := make([]int, 2, 5) // 创建一个数组,默认两个元素都为空,最多5个

Maps:map初始化,如不使用make,是没办法赋值的:

package main

import "fmt"

type Vertex struct {
    Lat, Long float64
}

var m map[string]Vertex

func main() {
    // m := make(map[string]Vertex)
    m["Bell Labs"] = Vertex{
        40.68433, -74.39967,
    }
    fmt.Println(m["Bell Labs"])
}

range的一个用法

可以使用_忽略返回:

package main

import "fmt"

func main() {
    pow := make([]int, 10)
    for i := range pow {
        pow[i] = 1 << uint(i) // == 2**i
    }
    for _, value := range pow {
        fmt.Printf("%d\n", value)
    }
}

func文档

Function values:函数参数传入一个函数

package main

import (
    "fmt"
    "math"
)

func compute(fn func(float64, float64) float64) float64 {
    return fn(3, 4)
}

func main() {
    hypot := func(x, y float64) float64 {
        return math.Sqrt(x*x + y*y)
    }
    fmt.Println(hypot(5, 12))

    fmt.Println(compute(hypot))
    fmt.Println(compute(math.Pow))
}

method

method更改自身,需要使用指针,同时根据上边struct,指针下取值可以直接使用v.X这类方法。具体看文档。

onvno commented 5 years ago

使用方法集与接口

package main

import (
    "fmt"
)

type List []int

func (l List) Len() int {
    return len(l)
}

func (l *List) Append(val int) {
    *l = append(*l, val)
}

type Appender interface {
    Append(int)
}

func CountInto(a Appender, start, end int) {
    for i := start; i <= end; i++ {
        a.Append(i)
    }
}

type Lener interface {
    Len() int
}

func LongEnough(l Lener) bool {
    return l.Len()*10 > 42
}

func main() {
    // A bare value
    var lst List
    // compiler error:
    // cannot use lst (type List) as type Appender in argument to CountInto:
    //       List does not implement Appender (Append method has pointer receiver)
    // CountInto(lst, 1, 10)
    if LongEnough(lst) { // VALID:Identical receiver type
        fmt.Printf("- lst is long enough\n")
    }

    // A pointer value
    plst := new(List)
    CountInto(plst, 1, 10) //VALID:Identical receiver type
    if LongEnough(plst) {
        // VALID: a *List can be dereferenced for the receiver
        fmt.Printf("- plst is long enough\n")
    }
}

讨论

在 lst 上调用 CountInto 时会导致一个编译器错误,因为 CountInto 需要一个 Appender,而它的方法 Append 只定义在指针上。 在 lst 上调用 LongEnough 是可以的因为 'Len' 定义在值上。

在 plst 上调用 CountInto 是可以的,因为 CountInto 需要一个 Appender,并且它的方法 Append 定义在指针上。 在 plst 上调用 LongEnough 也是可以的,因为指针会被自动解引用。

总结

在接口上调用方法时,必须有和方法定义时相同的接收者类型或者是可以从具体类型 P 直接可以辨识的:

指针方法可以通过指针调用 值方法可以通过值调用 接收者是值的方法可以通过指针调用,因为指针会首先被解引用 接收者是指针的方法不可以通过值调用,因为存储在接口中的值没有地址 将一个值赋值给一个接口时,编译器会确保所有可能的接口方法都可以在此值上被调用,因此不正确的赋值在编译期就会失败。

译注

Go 语言规范定义了接口方法集的调用规则:

类型 T 的可调用方法集包含接受者为 T 或 T 的所有方法集 类型 T 的可调用方法集包含接受者为 T 的所有方法 类型 T 的可调用方法集不包含接受者为 *T 的方法