1.内存分配
new,make(slice,map,channel) 一个返回指针,一个返回类型值
---------并发
1.使用channel和goroutine开发并行程序的能力。什么是goroutine? 具体统称为线程,进程,协程;分配和释放在堆空间上;仅比分配栈空间多一点消耗。
-----------goroutine
func ready(w string, t int) {
time.Sleep(time.Duration(t) * time.Second)
fmt.Println(w, "is ready!")
}
func main() {
//两个线程和主线程是同时运行的,若主线程不等待,则程序会直接退出
//go关键字开始一个goroutine
go ready("one", 1)
go ready("two", 2)
fmt.Println("main goroutine is waiting!")
//main函数等待足够长的时间,,让所有的线程都执行,
//但实际上没有办法知道当所有的线程都已经退出应当等待多久
//这时就要一些能够同goroutine通讯的机制channel
time.Sleep(2 * time.Second)
}
2.通过channel发送或者接受值,这些值只能是特定的类型channel类型,创建管道使用make,同时要定义发送或者接受值的类型 ci:=make(chan int),cf:=make(chan interface{})
ci <- 1发送整数1到管道ci, <-ci接受值并丢弃, i:=<-ci接受整数值并保持到i中
---------------
//全局变量,这样goroutine可以访问它
var c chan int
func ready(w string, t int) {
time.Sleep(time.Duration(t) * time.Second)
fmt.Println(w, "is ready!")
c <- 1
}
func main() {
c = make(chan int) //初始化c
go ready("one", 1)
go ready("two", 2)
fmt.Println("main goroutine is waiting not long!")
//等待,直到从channel上接收到一个值,且收到的值被丢弃了
//但是有时并不知道启动了多少个goroutine,通过select监听管道上输入的数据
<-c
<-c
}
3.虽然goroutine是并发执行的,但并不是并行运行的,即一次只能运行一个goroutine,通过cpu的时间片轮换机制来实现看起来的并行。利用runtime.GOMAXPROCS(n) 充分利用cpu的核数来设置并行执行的数量。
检查管道是否被关闭
x, ok := <-c
if ok == true {
fmt.Println(x)
} else {
fmt.Println("channel is close")
}
--------
func main() {
ch := make(chan int)
go shower(ch)
for i := 0; i < 10; i++ {
ch <- i
}
}
func shower(ch chan int) {
for {
j := <-ch //阻塞,等待,直到接收到了数字
fmt.Printf("%d\n", j)
}
}
2.gobyexample.com
------range-over-channels
func main() {
ch := make(chan string, 2)
ch <- "one"
ch <- "two"
//ch <- "three"
close(ch)
for v := range ch {
fmt.Println("ch=", v)
}
//a := <-ch
fmt.Println(a)
}
-----timers
func main() {
time1 := time.NewTimer(time.Second * 2)
<-time1.C
fmt.Println("Time1 expired")
stop1 := time1.Stop()
if stop1 {
fmt.Println("time1 stopped")
}
time2 := time.NewTimer(time.Second)
go func() {
<-time2.C
fmt.Println("time2 expired")
}()
stop2 := time2.Stop()
if stop2 {
fmt.Println("time2 stopped")
}
}
------regexp
func main() {
match, _ := regexp.MatchString("p([a-z]+)", "peach")
fmt.Println(match)
r, _ := regexp.Compile("p([a-z]+)ch")
fmt.Println(r.MatchString("peach"))
fmt.Println(r.FindString("peach punch"))
fmt.Println(r.FindStringIndex("peach punch"))
fmt.Println(r.FindStringSubmatch("peach punch"))
fmt.Println(r.FindStringSubmatchIndex("peach puch"))
fmt.Println(r.FindAllString("peach punch pinch", -1))
r = regexp.MustCompile("p([a-z]+)ch")
fmt.Println(r)
in := []byte("hello")
fmt.Println(in)
}
---------sha1-hashes
func main() {
//s := "abcdefg 0123"
h := sha1.New()
//h.Write([]byte(s))//h即是一个s字符串的哈希表
//bs := h.Sum(nil)
fmt.Println(h)
//fmt.Printf("%x\n", bs)//%x是将hash结果转换为hex string
}
-----------url-parsing
-----------command-line arguments
func main() {
args1 := os.Args
args2 := os.Args[1:]
args3 := os.Args[3]
fmt.Println(args1)
fmt.Println(args2)
fmt.Println(args3)
}
----------base64-encoding
func main() {
data := "abc123!?&$*()'-=@~"
sEnc := base64.StdEncoding.EncodeToString([]byte(data))
fmt.Println(sEnc)
sDec, _ := base64.StdEncoding.DecodeString(sEnc)
fmt.Println(string(sDec))
}
---------reading-files
func main() {
data, err := ioutil.ReadFile("note/0704/edit.html")
check(err)
fmt.Println(string(data))
f, err := os.Open("note/0704/edit.html")
check(err)
b1 := make([]byte, 5)
n1, err := f.Read(b1)
check(err)
fmt.Printf("%d bytes: %s\n", n1, string(b1))
o2, err := f.Seek(6, 0)
check(err)
b2 := make([]byte, 2)
n2, err := f.Read(b2)
check(err)
fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2))
o3, err := f.Seek(6, 0)
check(err)
b3 := make([]byte, 2)
n3, err := io.ReadAtLeast(f, b3, 2)
check(err)
fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))
r4 := bufio.NewReader(f)
b4, err := r4.Peek(5)
check(err)
fmt.Printf("5 bytes:%s\n", string(b4))
defer f.Close()
}
func check(e error) {
if e != nil {
panic(e)
}
}
----------writing-files
func main() {
d1 := []byte("hello\ngo\n")
err := ioutil.WriteFile("config_1", d1, 0644) //文件不存在时自动创建
check(err)
f, err := os.Create("config_2")
check(err)
defer f.Close()
d2 := []byte{115, 111, 48, 97, 65}
n2, err := f.Write(d2)
check(err)
fmt.Printf("write %d bytes\n", n2)
n3, err := f.WriteString("writestring\n") //继续在上面的内容后面添加
fmt.Printf("writestring %d bytes\n", n3)
f.Sync()
w := bufio.NewWriter(f)
n4, err := w.WriteString("buffered\n")
fmt.Printf("write %d bytes\n", n4)
w.Flush()
}
---------environment variables
func main() {
os.Setenv("FOO", "1")
fmt.Println("FOO", os.Getenv("FOO"))
fmt.Println("BAR", os.Getenv("BAR"))
for _, e := range os.Environ() {
pair := strings.Split(e, "=")
fmt.Println(pair[0])
}
}
----------map sort
----------exit
func main() {
defer fmt.Println("defer func")
os.Exit(3) //os.Exit(0)没有打印 -1
}
---------
1.格式
函数,结构体的调用和定义
结构体,构造函数,相关方法的定义
必须要用api.go 用于导出接口给service和applet。必须有两个文件main.go service.go
2.数据
对计算机而已,数据就是1和0的序列,一个序列可以存储在内存中,但内存中的数据会随着关机而消失。长久储存的话在光盘或者硬盘中。
文件系统file system .当前目录 ..父目录 目录也是文件 超级用户root 拥有所有的文件 硬链接数hard link 软链接soft link umask
计算机本质上是对数据进行处理的工具,文件是数据储存的逻辑载体
3.web框架 gin 还有对应的beego
200 成功
3.. 重定向
404 请求错误
5.. 服务器错误
4.
public负责浏览器界面相关处理,请求routes文件夹下的资源,进行数据解析,然后调用model层的接口操作domain层的数据库。
session:
通过用户名加密码来确定用户的身份,
浏览器允许网页服务器在浏览器里存一段数据。浏览器第一次访问时,服务器的响应就会包含需要浏览器请求的数据,浏览器就会把数据保存起来到本地;浏览器再次访问同一个网页在请求里就会包含这段数据,即为cookie
5.gin----readme
GET
参数在路径里
查询url参数
POST:
对请求的处理
gin.H{} ==== map[string]interface{}
gin.Default()---gin.New()
(c *gin.Context)
c.HTML(200,"index.html",gin.h{}) c.JSON(http.StatusOK,msg) c.XML(200,gin.H{})
6.接口
接口类型必须被赋值于有相应方法的变量才有意义 var b Tester=&Mytest{}
p---package
t---type
v---variable
f---function
var a interface{}=nil 只有当接口存储的类型和对象都是nil时,接口才等于nil
package main
import (
"fmt"
)
type Vter interface {
vt(a interface{})
}
type Pter interface {
pt(a interface{})
}
type User struct {
Id int
Name string
}
func (this User) vt(a interface{}) {
fmt.Printf("type:%T,value:%v,paragram:%v\n", this.Id, this.Id, a)
}
func (this *User) pt(a interface{}) {
fmt.Printf("name:%v,type:%T\n", this.Name, this.Name)
}
func main() {
u := User{1, "jack"}
p := &u
Vter(u).vt("hello") //接口的使用
Vter(p).vt("world")
var s = Vter(u) //定义s为接口类型,不能s.User.Id
}
结构体,方法,接口
go中的struct替代class实现面向对象的编程
给自己定义的类型添加方法T,*T
===用结构体计算面积===接口实现排序===
-------------------------------------
type Rect struct {
x, y float32
}
func (r *Rect) Area() float32 {
return r.x * r.y
}
func (r Rect) prim() float32 {
return r.x + r.y
}
func NewRect(x, y float32) *Rect {
return &Rect{x, y}
}
func main() {
r := NewRect(1.0, 3.5)
//r.x不能用Rect.x,要用对象实例去. 即该类型的对应变量(对象)
//结构体的初始方法 a:=Rect{2,3} Rect{} Rect{x:3,y:44} &Rect{3,3} new(Rect)
fmt.Println(r.x, r.y, r.Area(), r.prim())
Rect.x = 22
}
-----------------------------------
type S1 struct {
Id int
Name string
}
type Interger int
func (this *S1) Set() *S1 {
this.Id = 3
this.Name = "pa"
return this
}
//并不一定在接收则都用指针,不需要改变对应类型的值时可以不用
func (this S1) print() {
fmt.Println(this)
}
func (this Interger) print() {
fmt.Printf("value:%v,type=%T\n", this, this)
}
func NewS1(a int, b string) *S1 {//构造函数
return &S1{a, b}
}
func main() {
s := &S1{Id: 33, Name: "DF"}
fmt.Println(s)
fmt.Println(s.Set())
s2 := NewS1(1, "它们")
s2.print()
i := Interger(4) //类型是main.Interger不是int
i.print()
}
---------------------------
type Sorter interface {
len() int
less(int, int) bool
swap(int, int)
}
type X []int
type Y []string
func (p X) len() int {
return len(p)
}
func (p X) less(i, j int) bool {
return p[i] > p[j]
}
func (p X) swap(i, j int) {
p[i], p[j] = p[j], p[i]
}
func Sort(I Sorter) {
for i := 0; i <= I.len(); i++ {
for j := i + 1; j < I.len(); j++ {
if I.less(i, j) {
I.swap(i, j)
}
}
}
}
func main() {
arr1 := []int{12, 9, 8, 66, 15} //错误,一定要要自己定义的类型
arr := X{12, 9, 8, 66, 15}
fmt.Printf("arr1=%T,arr=%T\n", arr, arr1) //arr1=main.X,arr=[]int
fmt.Println(arr)
Sort(arr)
fmt.Println(arr)
}
go包(标准库)的学习
http://blog.studygolang.com/2012/11/%E5%AD%A6%E4%B9%A0go%E5%8C%85/
(1).overview--index(看函数和类型,常量)
以Time包为例
定义了一些常量
定义了Duration、location等一些类型
有After,Sleep,Tick三个全局函数
(2).关注类型及其方法
以Duration为例
看其定义type
看其对应的方法
time. 若是l,表示是常量constant
time.Second ---1S 是Duration类型下面定义的一个常量,type Duration int64 自己定义的新类型,表示两个时间的间隔
time.Duration(v1) 表示将v1装换为指定的类型,不只是函数才能用括号
multiple-value t1.Date() in single-value context 表示函数的返回值有多个而接受者只有一个
版权声明:本文为博主原创文章,未经博主允许不得转载。