Open onvno opened 5 years ago
beego 国产很成熟 Martini 很成熟 Macaron 类似 Martini,更自由 gin 用了都说好
beego:官方文档
beego:官方
echo:官方
iris:官方
go语言web框架比较:gin vs iris vs echo
综合以上各个测试结果可以看出,gin以及iris都是非常优秀的框架,gin的优势比其他稍微大点,iris次之,而echo相应差一点。 本次测试只是简单测试了一下3个框架的并发和json相关。对比结果,不包括生态和工具的完善度等等。如果测试有什么不完善的地方,欢迎交流。
最终选择gin
教程:使用 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{})
}
web:gin
orm:gorm
database:sqlite3
全文检索:wukong
文件存储:七牛云存储smms图床
配置文件 go-yaml
目录
-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/)
Gin路由全介绍中文: Golang 微框架 Gin 简介 👍👍👍
查询数据库用法是发现有些函数用法比较特殊: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())
}
下边定义的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)
}
数组的长度也是数组的类型一部分,所以需要和类型在一起:
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)
}
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"])
}
可以使用_
忽略返回:
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)
}
}
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更改自身,需要使用指针,同时根据上边struct
,指针下取值可以直接使用v.X
这类方法。具体看文档。
value
的,参数可以是value
和pointer
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 的方法
升级
删除原版本,重新安装
To uninstall, delete the /usr/local/go directory by:
Install the new version Go to the downloads page and download the binary release suitable for your system.
Extract the archive file To extract the archive file:
Make sure that your PATH contains /usr/local/go/bin
How to update the Go version