- package main
-
- import (
- "bytes"
- "encoding/xml"
- "errors"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "os/user"
- "reflect"
- "runtime"
- "strconv"
- "sync"
- "time"
- )
-
- //全局变量
- var name,age="jacky",18
-
- func main() {
- //fmt.Println("test main")
- //var b=util.Isempty("abc")
- //fmt.Println(b)
- //util.Hi()
- //
- //fmt.Println(name,age)
- //fmt.Println(util.Name1,util.Age1)
- //
- //f:=closure()
- //fmt.Println(f())
- //fmt.Println(f())
- //fmt.Println(f())
-
- //a:=6
- //b:="abc"
- slice map channel interface func 是引用类型
- //arr:=[]string{"a","b","c"}
- //c:=100//传指针地址,会修改原先的值
- //testValueAndReference(a,b,arr,&c)
- //
- //fmt.Println(a)
- //fmt.Println(b)
- //fmt.Println(arr)
- //fmt.Println(c)
-
- //testStrut()
-
- //p:=People{"figo",18,69}
- //p.run()
- //fmt.Println("跑步后体重",p.Weight)
- //
- //allEat(&p)
- //
- //a:=Animal{"dog",false}
- //allEat(&a)
-
- //assert()
-
- //result,e:=testError(18)
- //if result {
- // fmt.Println("success")
- //}else {
- // fmt.Println(e.Error())
- //}
- //testDefer()
- //a:=testDeferReturn()
- //fmt.Println("得到返回值a=",a)
-
- //testPanic()
- //testRecover()
-
- //testUserInfo()
-
- //testIO()
- //testReaderAndWriter()
- //testIoUtil()
- //testReflect()
-
- //testXML()
-
- //testLog()
-
- //testSleep()
- //testGoRoutine()
- //testWaitGroup()
- //testMutex
- //testRWMutex()
- //testChannel()
- //testBufferChan()
- }
- /**
- 闭包,将局部变量能够返回,
- 返回的是函数表量
- */
- func closure() func() int {
- a:=1
- return func() int {
- a=a+1
- return a
- }
-
- }
- /**
- 测试值传递和引用传递
- */
- func testValueAndReference(a int,b string,arr []string,c *int) {
- a=10
- b="test"
- arr[0]="great"
- arr[1]="job"
- *c=123
- }
- /**
- 定义接口
- */
- type Eat interface {
- eat()
- }
- /*
- People和Animal都实现了eat方法,通过该接口调用实现多态
- */
- func allEat(eat Eat) {
- eat.eat()
- }
-
- type People struct {
- Name string
- Age int
- Weight int
- }
- //方法属于结构体
- func( p *People) run() {
- fmt.Println(p.Name,"当前体重",p.Weight)
- p.Weight=p.Weight-1
- }
- /**
- 实现接口Eat中的eat方法
- */
- func( p *People) eat() {
- fmt.Println(p.Name,"正在吃饭")
-
- }
-
- type Animal struct {
- Name string
- CanFly bool
- }
- /**
- 动物也实现接口Eat中的eat方法
- */
- func(a *Animal) eat() {
- fmt.Println(a.Name,"正在吃饭")
- }
- /**
- 测试结构体
- */
- func testStrut() {
- peo1:=People{"andy",18,69}
- peo2:=People{Age: 16,Name: "anna"}
- fmt.Printf("%p\n",&peo1)
- fmt.Printf("%p\n",&peo2)
- fmt.Println(peo1)
- fmt.Println(peo2)
- peo1.Name="jacky"
- fmt.Println(peo1)
- var peo3 People
- peo3=peo1
- //结构体是值类型,这里虽然改变了name但是peo1不受影响
- peo3.Name="tom"
- fmt.Println("peo1=",peo1)
- fmt.Println("peo3=",peo3)
-
-
- //结构体指针
- peo5:=new(People)
- peo5.Name="rose"
- peo5.Age=15
- fmt.Println("peo5",peo5)
-
- peo6:=&People{"figo",18,66}
- fmt.Println("peo6",peo6)
- fmt.Println(peo5==peo6)
-
- //因为定义的是指针,所以修改后peo5会跟着改变
- peo7:=peo5
- peo7.Name="mary"
- fmt.Println("peo5",peo5)
- fmt.Println("peo7",peo7)
- fmt.Println(peo5==peo7)
-
- }
- /**
- 断言
- */
- func assert() {
- var i interface{}=123
- //断言是否是int,是返回值给result,ok接收断言是否准确,当为false时,result会赋默认值
- result,ok:=i.(int)
- fmt.Println(result,ok)
-
- result1,ok1:=i.(float64)
- fmt.Println(result1,ok1)
- }
- /**
- 测试返回error
- */
- func testError(age int)(result bool,e error) {
- if age<18 {
- result=false
- //e=errors.New("年龄小于18岁,不宜观看")
- //两种定义都可以
- e=fmt.Errorf("年龄%d,小于18岁,不易观看",age)
- return
- }else {
- result=true
- e=errors.New("年龄大于等于18岁,宜观看")
- return
- }
- }
- /**
- defer推迟执行
- 顺序是 A C E D B
- defer函数是放入栈中,先进后出
- */
-
- func testDefer() {
- fmt.Println("执行步骤A")
- defer func() {
- fmt.Println("推迟执行步骤B")
- }()
- fmt.Println("执行步骤C")
- defer func() {
- fmt.Println("推迟执行步骤D")
- }()
- fmt.Println("执行步骤E")
- }
- /**
- 延迟执行带返回值
- 如果这里不定义r变量,那么返回的a将等于19,定义了
- 返回是20
- */
- func testDeferReturn() (r int) {
- a:=18
- fmt.Println("执行步骤A,a=",a)
- defer func() {
- //这么写是19
- //a++
- //这么写是20
- r=a+1
- fmt.Println("执行步骤B,r=",r)
- }()
- a++
- fmt.Println("执行步骤C,a=",a)
- return a
- //定义了r,可以直接写return
- //return
- }
- /**
- 测试异常抛出,相当于java的throw
- */
- func testPanic() {
- fmt.Println("test")
- defer func() {
- fmt.Println("抛出异常后,这里还是会被执行的")
- }()
- panic("抛出异常")
- fmt.Println("这里不会被执行")
-
- }
- /**
- 测试从异常中恢复recover()函数,用于捕获异常
- 然后从异常中恢复
- */
- func testRecover() {
- fmt.Println("start")
- defer func() {
- if err:=recover();err!=nil{
- fmt.Println("出现异常",err)
- fmt.Println("继续执行其他逻辑")
- }
- }()
- panic("抛出异常测试")
- }
- /**
- 获取计算机用户信息
- */
- func testUserInfo() {
- u,e:=user.Current()
- if e!=nil{
- fmt.Println(e)
- return
- }
- fmt.Println(u.Uid)
- fmt.Println(u.Gid)
- fmt.Println(u.Name)
- fmt.Println(u.HomeDir)
-
- }
- /**
- 文件或文件夹增删改查测试
- */
- func testIO() {
- //创建文件夹 test文件夹必须存在否则报错
- //err:=os.Mkdir("E:\\test1\\gotest",os.ModeDir)
- //if err!=nil{
- // fmt.Println(err)
- // return
- //}
- //fmt.Println("文件夹创建成功")
-
- //创建文件夹 test文件夹不存在也可以成功
- //err1:=os.MkdirAll("E:\\test1\\gotest",os.ModeDir)
- //if err1!=nil{
- // fmt.Println(err1)
- // return
- //}
- //fmt.Println("文件夹创建成功")
-
- //创建文件
- //f,err:=os.Create("E:\\test\\gotest\\test.txt")
- //if err!=nil {
- // fmt.Println(err)
- // return
- //}
- //fmt.Println("文件创建成功,文件名=",f.Name())
- //文件夹重命名,gotest文件夹下必须没有文件,否则无法重命名
- //err1:=os.Rename("E:\\test\\gotest","E:\\test\\gotestnew")
- //if err1!=nil {
- // fmt.Println(err1)
- // return
- //}
-
- //读取文件
- //f,err:=os.Open("E:\\test\\gotestnew\\新建文本文档.txt")
- //if err!=nil {
- // fmt.Println(err)
- // return
- //}
- //fi,e:=f.Stat()
- //if e!=nil {
- // fmt.Println(e)
- // return
- //}
- //fmt.Println(fi.Name(),fi.Size(),fi.IsDir(),fi.Mode())
-
-
- //删除文件或文件夹,文件或文件夹必须存在,否则报错
- //e:=os.Remove("E:\\test\\gotestnew\\新建文本文档.txt")
- //if e!=nil {
- // fmt.Println("删除失败",e)
- // return
- //}
- //fmt.Println("删除成功")
-
- //文件或文件夹不存在也不会报错
- //e1:=os.RemoveAll("E:\\test\\gotestnew")
- //if e1!=nil {
- // fmt.Println("删除失败",e1)
- // return
- //}
- //fmt.Println("删除成功")
-
-
- testReflect()
- }
- /**
- 输入输出流测试
- */
- func testReaderAndWriter() {
- //打开文件open,只读
- //f,e:=os.Open("E:\\test\\gotestnew\\test.txt")
- //openFile可读可写
- f,e:=os.OpenFile("E:\\test\\gotestnew\\test.txt",os.O_APPEND,0660)
-
- if e!=nil{
- fmt.Println("读取文件失败",e)
- return
- }
- //获取fileinfo信息
- fi,er:=f.Stat()
- if er!=nil{
- fmt.Println("读取文件失败",er)
- //return
- //不存在则创建
- os.Create("E:\\test\\gotestnew\\test.txt")
- }
- b:=make([]byte,fi.Size())
- //输入流,读取
- f.Read(b)
- v:=string(b)
- fmt.Println("读取到的值=",v)
- //输出流,写入
- f.Write([]byte("\r\n hello,world!"))
- f.WriteString("great")//内部是write
-
- }
- /**
- 测试ioutil
- */
- func testIoUtil() {
- //读取file,e用_表示不处理
- //f,_:=os.Open("E:\\test\\gotestnew\\test.txt")
- //b,_:=ioutil.ReadAll(f)
- //fmt.Println(string(b))
-
- //直接读取,这里是定义变量需要加:,否则使用var 和变量类型
- b,_:=ioutil.ReadFile("E:\\test\\gotestnew\\test.txt")
- fmt.Println(string(b))
-
- ioutil.WriteFile("E:\\test\\gotestnew\\test.txt",[]byte("\r\n这里是写入的新数据"),0666)
- //这里是赋值,不需要加:
- b,_=ioutil.ReadFile("E:\\test\\gotestnew\\test.txt")
- fmt.Println(string(b))
-
- //读取文件夹
- fileArr,e:=ioutil.ReadDir("E:\\test\\gotestnew\\")
- if e!=nil{
- fmt.Println(e)
- }
- for _,f:=range fileArr{
- fmt.Println(f.Name(),f.Size(),f.Mode(),f.IsDir(),f.ModTime())
- }
-
- str := "abc"
- //通过for打印每个字符
- fmt.Println("-----循环第一种用法------")
- for i := 0; i < len(str); i++ {
- fmt.Printf("str[%d]=%c\n", i, str[i])
- }
- fmt.Println("-----循环第二种用法------")
-
- for i := range str { //第2个返回值,默认丢弃,返回元素的位置(下标)
- fmt.Printf("str[%d]=%c\n", i, str[i])
- }
- fmt.Println("-----循环第二种用法,两个参数,第一个是索引,第二个是值------")
-
- for _, item := range str { //第2个返回值,默认丢弃,返回元素的位置(下标)
- fmt.Printf("%c\n",item)
- }
-
- }
- type Student struct {
- Name string
- Age int
- }
- /**
- 测试反射
- */
- func testReflect(){
- //s:=Student{"andy",18}
- s:=new(Student)
- s.Name="rose"
- s.Age=18
- fmt.Println(reflect.TypeOf(s))
- fmt.Println(reflect.ValueOf(s))
- }
-
- /**
- 测试XML读取
- */
- type Person struct {
- XMLName xml.Name `xml:"person"`
- Id int `xml:"id,attr"`
- Name string `xml:"name"`
- Address string `xml:"address"`
-
- }
-
- func testXML() {
- //读取xml
- peo:=new(Person)
- b,_:=ioutil.ReadFile("person.xml")
- fmt.Println(string(b))
- xml.Unmarshal(b,peo)
- fmt.Println(peo)
-
- //生成xml
- p1:=Person{Id:1,Name:"jacky",Address: "sh"}
- b1,_:=xml.MarshalIndent(p1,""," ")
- b2:=append([]byte(xml.Header),b1...)
- ioutil.WriteFile("E:\\test\\gotestnew\\person.xml",b2,0666)
-
-
-
- }
- /**
- 测试日志打印
- */
- func testLog() {
- f,e:=os.OpenFile("E:\\test\\gotestnew\\log.txt",os.O_APPEND|os.O_CREATE,0777)
- if e!=nil{
- fmt.Println(e)
- }
- logger:=log.New(f,"[info]",log.LstdFlags)
- logger.Println("打印日志测试")
-
- }
- /**
- 测试线程睡眠
- */
- func testSleep() {
- fmt.Println("程序开始")
- time.Sleep(2e9)//单位纳秒 这里表示2秒
- time.AfterFunc(2e9, func() {
- fmt.Println("2秒后,开始执行这里")
- })
- //主协程这里睡眠一下,不然看不到另外一个协程的执行结果
- time.Sleep(3e9)
- fmt.Println("程序执行结束")
-
-
- }
-
- /**
- 协程测试
- */
- func testGoRoutine() {
- for i:=1;i<10;i++{
- go testGo()
- }
- //主协程睡眠一会,免得看不到子协程打印日志
- time.Sleep(3e9)
- }
- func testGo() {
- for i:=1;i<10;i++{
- fmt.Println("当前协程编号",goID())
- fmt.Println("当前值=",i)
- }
- }
- /**
- 获取协程编号
- */
- func goID() uint64 {
- b := make([]byte, 64)
- b = b[:runtime.Stack(b, false)]
- b = bytes.TrimPrefix(b, []byte("goroutine "))
- b = b[:bytes.IndexByte(b, ' ')]
- n, _ := strconv.ParseUint(string(b), 10, 64)
- return n
- }
-
- /**
- 测试计数器WaitGroup,相当于java里面的countdownlatch
- */
- func testWaitGroup() {
- var wg sync.WaitGroup
- wg.Add(10)
- for i:=0;i<10;i++{
- go func() {
- fmt.Println(i)
- wg.Done()
- }()
- }
- wg.Wait()
- fmt.Println("执行完成")
- }
-
- /**
- 测试互斥锁与读写锁
- */
- var(
- num=100
- wg sync.WaitGroup
- m sync.Mutex
- )
- func testMutex() {
- //wg.Add(1000)
- for i:=0;i<1000;i++{
- go deductStock()
-
- }
- //不加锁库存会变成-1
- //wg.Wait()
- fmt.Println("剩余库存=",num)
- }
- /**
- 扣减库存,加互斥锁(分布式环境无效,单机环境可以)
- */
- func deductStock() {
- m.Lock()
- if num>0{
- num=num-1
- }
- m.Unlock()
- //wg.Done()
-
- }
- /**
- 测试读写互斥锁
- */
- func testRWMutex() {
- var rwm sync.RWMutex
- var wg sync.WaitGroup
- wg.Add(100)
- m:=make(map[int]int)
- for i:=0;i<100;i++{
- go func(j int) {
- rwm.Lock()
- //又读又写,就有可能报出:fatal error: concurrent map writes
- m[i]=j
- fmt.Println(m)
- rwm.Unlock()
- wg.Done()
- }(i)
- }
- wg.Wait()
- fmt.Println("多协程执行完成")
- }
- /**
- 协程间通信用chan,chan在读写的时候都会阻塞
- */
- func testChannel(){
- ch:=make(chan int)
-
-
- go func() {
- fmt.Println("子协程执行开始后,阻塞在这里等等获取ch里面的数据")
- ch<-100
- fmt.Println("子协程执行结束")
-
-
- }()
-
- //go func() {
- // fmt.Println("开始去ch里面的数据")
- // a:=<-ch
- // fmt.Println("取完ch里面的数据了",a)
- //
- //}()
- fmt.Println("主协程开始读取")
- a:=<-ch
- fmt.Println("主协程执行完成",a)
- }
-
- func testBufferChan() {
- ch:=make(chan int,3)
- ch<-1
- ch<-1
- ch<-1
- //超出个数就会阻塞,除非往外取一个<-ch
- //ch<-1
-
- fmt.Println("程序运行结束")
- }
-
-
-