Open shownb opened 6 years ago
如果包名不是以 . 或 / 开头,如 "fmt" 或者 "container/list",则 Go 会在全局文件进行查找;如果包名以 ./ 开头,则 Go 会在相对目录中查找;如果包名以 / 开头(在 Windows 下也可以这样使用),则会在系统的绝对路径中查找。
类型
函数参数、返回值以及他们的类型统称为函数签名
尽量使用命名返回值:会使代码更清晰,更剪短,同时更加容易读懂
空白符 _
new和make
new 和 make 均是用于分配内存:new 用于值类型和用户定义的类型,如自定义结构,make 用于内置引用类型(切片、map 和管道)。它们的用法就像是函数,但是将类型作为参数:new(type)、make(type)。new(T) 分配类型 T 的零值并返回其地址,也就是指向类型 T 的指针(详见第 10.1 节)。它也可以被用于基本类型:v := new(int)。make(T) 返回类型 T 的初始化之后的值,因此它比 new 进行更多的工作(详见第 7.2.3/4 节、第 8.1.1 节和第 14.2.1 节)new() 是一个函数,不要忘记它的括号
函数的闭包 闭包是一个函数值,它引用了函数体之外的变量。 这个函数可以对这个引用的变量进行访问和赋值;换句话说这个函数被“绑定”在这个变量上。
func adder() func(int) int {
sum := 0 //sum被锁住了
return func(x int) int {
sum += x
return sum
}
}
package main
import (
"fmt"
)
type KfPig interface {
GetPork() string
GetSoup(giveWater int) int
GetNoodle() int
}
type Pig struct {
name []string
}
func (this *Pig) GetPork() string {
fmt.Printf("%v won and be killed\n", this.name[0])
return this.name[0]
}
func (this *Pig) GetSoup(giveWater int) int {
fmt.Printf("many pigs are bathing..got 10L water\n")
return 10
}
func (this *Pig) GetNoodle() int {
fmt.Printf("many pigs are running..got 5kg Noodles\n")
return 5
}
func Mix(x KfPig) {
Pork := x.GetPork()
Soup := x.GetSoup(20)
Noodle := x.GetNoodle()
fmt.Printf("%v + %v + %v = BestPorkRamen\n", Pork, Soup, Noodle)
}
func main() {
pigs := Pig{name: []string{"p1", "p2", "p2"}}
Mix(&pigs)
fmt.Printf("done")
}
超级有用的解析接口的文章 https://studygolang.com/articles/12266
https://studygolang.com/articles/7123
https://porson.github.io/2017/02/05/Go语言关于Interface的理解与思考/
接口的作用就在于去作为"中间体"去调用结构体的成员方法 没有必要再去对接口内部的方法进行重新定义!!总之,使用接口可以非常灵活,而且与具体的实现做了解耦,如果以后有其他的实现类,只需要实现接口就可以了,而不用去改使用的时候的代码。
sanic vs go sanic with mysql(massive 10 pool)
# encoding: utf-8
from sanic import Sanic
from sanic.response import html
from model.tornadb import Conn
from config import Mysql_Setting
db = Conn()
app = Sanic()
@app.listener("before_server_start")
async def get_pool(app,loop):
await db.create_poll(**Mysql_Setting)
@app.route("/")
async def test(request):
many = await db.query("select id from t")
return html(many)
if __name__ == '__main__':
app.run(host="0.0.0.0",port=8080,access_log=False)
Concurrency Level: 10 Time taken for tests: 15.777 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 1540000 bytes HTML transferred: 560000 bytes Requests per second: 633.83 [#/sec] (mean) Time per request: 15.777 [ms] (mean) Time per request: 1.578 [ms] (mean, across all concurrent requests) Transfer rate: 95.32 [Kbytes/sec] received
package main
import (
"fmt"
"io"
"net/http"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
var db *sql.DB
var err error
func init() {
db, err = sql.Open("mysql", "root:toortoor@/typecho?charset=utf8")
if err != nil {
panic(err.Error())
}
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)
db.Ping()
}
func test(w http.ResponseWriter, r *http.Request) {
rows,_ := db.Query("select id from t")
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
panic(err.Error())
}
fmt.Printf("%s\n", id)
}
rows.Close()
io.WriteString(w, "rows")
}
func main() {
defer db.Close()
fmt.Println("start")
http.HandleFunc("/", test)
http.ListenAndServe(":8080", nil)
}
Concurrency Level: 10 Time taken for tests: 10.768 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 1200000 bytes HTML transferred: 40000 bytes Requests per second: 928.70 [#/sec] (mean) Time per request: 10.768 [ms] (mean) Time per request: 1.077 [ms] (mean, across all concurrent requests) Transfer rate: 108.83 [Kbytes/sec] received
多协程mysql https://studygolang.com/articles/7494 http://penghui.link/articles/2017/12/go_mysql.html
mysql 操作 golang学习之旅:使用go语言操作mysql数据库 golang连接mysql操作示例增删改查 MySQL唯一键重复的处理 []()
boltdb golang boltdb的学习和实践
package main
import (
"fmt"
"io"
"net/http"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
var db *sql.DB
var err error
func init() {
db, err = sql.Open("mysql", "root:toortoor@tcp(127.0.0.1:3306)/typecho?charset=utf8")
if err != nil {
panic(err.Error())
}
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)
//想验证是不是可以链接,清用ping来检查
db.Ping()
}
func test(w http.ResponseWriter, r *http.Request) {
ch := make(chan string)
go func () {
rows,_ := db.Query("select id from t")
defer rows.Close()
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
panic(err.Error())
}
ch <- id
//fmt.Printf("%s\n", id)
}
close(ch)
}()
for e := range ch{
fmt.Printf("%s\n", e)
}
io.WriteString(w, "rows")
}
func main() {
defer db.Close()
fmt.Println("start")
http.HandleFunc("/", test)
http.ListenAndServe(":8080", nil)
}
Golang 微框架 Gin 简介 https://www.jianshu.com/p/a31e4ee25305 Gin实战:Gin+Mysql简单的Restful风格的API golang实践-如何实现高性能的定时任务管理器
框架写法参考 https://github.com/josephspurrier/gowebapp https://github.com/mlabouardy/movies-restapi
Form:存储了post、put和get参数,在使用之前需要调用ParseForm方法。 PostForm:存储了post、put参数,在使用之前需要调用ParseForm方法。 MultipartForm:存储了包含了文件上传的表单的post参数,在使用前需要调用ParseMultipartForm方法。
切片里面的坑。 如果将切片传进函数,但是如果再用append的话,可能返回的是新切片。 切片能够在函数能够引用传送,估计是建立在固定了长度之后。 如何避开 Go 中的各种陷阱 http://newton.sh/2016/11/07/如何避开-Go-中的各种陷阱/
Go 标准库剖析 1(transport http 请求的承载者)https://segmentfault.com/a/1190000003735562
如何实现支持数亿用户的长连消息系统 https://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209727496&idx=1&sn=86b64ddadcc91bc6b0741a870692b3c0
不要用apt-get install 安装,如果安装了,用这个反安装apt-get purge golang-go go的安装 查看最新版 https://golang.org/dl/ 不同版本,不同系统,不同arch都可以。然后设置一下PATH让系统找到go的bin旧可以了。 tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
添加 /usr/local/go/bin 到PATH环境变量: 全局添加/etc/profile 或者 $HOME/.profile
还有就是工作目录workspace,默认是$HOME/go,你不喜欢也可以自己改变 编辑.bashrc或者.bash_profile
让他生效
编译 for Mac
交叉编译
包
表达式 是由数字、算符、数字分组符号(括号)、变量和常量等以能求得数值的有意义排列方法所得的组合。 函数签名 函数参数、返回值以及它们的类型被统称为函数签名。
变量声明
具体参考 http://www.wklken.me/posts/2014/03/02/02-type-var-const.html
类型
byte 是uint8的别名 rune 是int32的别名 字符串是bytes的集合
函数
如果一个函数有多个返回值,那么这些返回值必须用()括起来。
指针
Go 具有指针.指针保存了变量的内存地址. 类型 *T 是指向类型 T 的值的指针。其零值是 nil 。
& 符号会生成一个指向其作用对象的指针。
* 符号表示指针指向的底层的值。
golang的goroutine是如何实现的? https://www.zhihu.com/question/20862617
[5]int{1,2,3} []int{1,2,3}就变成数组和切片了
数组
数组是具有相同 唯一类型 的一组已编号且长度固定的数据项序列 声明的格式是 var identifier [len]type
a[x] 是 (a)[x] 的简写形式,因此上面代码中的 (arr)[0] 可以替换为 arr[0]。
切片
使用make创建一个切片func make ([]type,len,cap) 声明切片的格式是: var slice []type(不需要说明长度)。 切片的初始化格式是:var slice1 []type = arr1[start:end] 切片自己不拥有任何数据,它只是底层数组的一种表示。切片在内部可由一个结构体表示.当切片传递给函数时,即使它通过值传递,指针变量也将引用相同的底层数组。
内存优化,可以用copy(dst,src[]type)int 来生成一个切片副本,原来的给垃圾回收。 切片追加 func append(s[]type,x ... type) []type 追加后新切片是旧的两倍容量。 语法糖 可以用...的形式进一个可变参函数 如:append(sliceold,slice...)
可变参函数
可变参数函数的工作原理是把可变参数转换为一个新的切片。
Maps
make(map[type of key]type of value) 如:make(map[string]int) map 的零值是 nil。如果你想添加元素到 nil map 中,会触发运行时 panic。因此 map 必须使用 make 函数初始化。 也可以这样初始化 var a map[string]int = map[string]int{} 这样就不是nil了 value, ok := map[key] ok返回true代表由这个key map是引用类型
字符串
Go语言中的字符串是一个字节(byte)切片 byteSlice := []byte{0xe6,0xa0,0x88} 注意 这个切片,字符是"栈",占用了3个byte
结构体
声明结构体时也可以不用声明一个新类型,这样的结构体类型称为 匿名结构体(Anonymous Structure)。 编程中有时候需要一个临时的 struct 来封装数据,而这个 struct 的结构在其它地方又不会被二次复用,可以使用匿名 struct 来实现。(个人感觉是,相当于只能创造一个实例,不通用,因为没新类型,没兄弟啰~)
又例如
结构体就是一个类,通常保存属性,方法相当于类的函数,不过有两种类型的接受者(对象),一种是值,一种是指针,指针能改变结构体中的属性值。 一个结构体( struct )就是一个字段的集合。 (而 type 的含义跟其字面意思相符。) 结构体字段使用点号来访问。
当结构体struct1是指针时 go允许我们用 struct1.字段 来代替显式的解引用 (*struct1).字段
初始化一个结构体实例的更简短和惯用的方式如下:
或者:
方法
方法接收者 出现在 func 关键字和方法名之间的参数中。
你可以对包中的 任意 类型定义任意方法,而不仅仅是针对结构体。 但是,不能对来自其他包的类型或基础类型定义方法。(意思是如果你要对int动手动脚,是不行的,需要另外type newint int)
方法可以与命名类型或命名类型的指针关联。方法也可以带参数
关于接口,这个文章比较有意思https://studygolang.com/articles/7123
golang 建立web服务器 http包源码详解