go 入門1 —— 基礎語法

參考:https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/preface.md

主要內容爲,基本類型,流程控制,對象接口,方法調用,異常等方面

package main

import (
	"errors"
	"fmt"
	"runtime"
	"time"
)

const (
	aaaa=1
	WHITE= iota
	BLACK
	HEHE
)

var (
	AA=1
	aa=1
)

type 	(
	//method
	func1 func(int)int
 		testInt func(int) bool
	// 定義一個 DivideError 結構
	 DivideError struct {
		dividee int
		divider int
}
	hehe struct {
		width ,height int
		name string
	}
	heheqq struct {
		hand hehe
		hh,ww int
	}

	ha struct {
		//匿名爲繼承
		heheqq
		aa int
	}
    Men interface {
    	say()
	}
)
/**Methods Receivers	Values
				(t T)	T and *T
				(t *T)	*T
如果是值接收者,實體類型的值和指針都可以實現對應的接口;如果是指針接收者,那麼只有類型的指針能夠實現對應的接口。
**/
func (hh *heheqq) say1()  {
	fmt.Println(111)
}

func  area1(hh heheqq)int  {
	return hh.hh*hh.ww
}

func (hh *heheqq) area()int  {
	return hh.hh*hh.ww
}

//explain
func main(){
	fmt.Println("hello world")
	//baseTypeTest
	baseTypeTest()
	//if for switch
	gogoTest()
	//methodTest
	methodTest()
	//error panic recover
	errorTest()
	//object
	objectTest()
	//goroutine
	gogo()
	//channel
	channelTest()
	//select
	selectTest()
	//time out
	timeoutTest()
}
func timeoutTest()  {
	c := make(chan int)
	o := make(chan bool)
	go func() {
		for {
			select {
			case v := <- c:
				println(v)
			case <-time.After(5*time.Second):
				println("timeout")
				o <- true
				break
			//default:
			//	fmt.Println("heheda")
			//
			}
		}
	}()
	<- o
}
func selectTest()  {
	c :=make(chan int)
	quit :=make(chan int)
	go func() {
		for i:=1; i<10 ; i++ {
			fmt.Println(<-c)
		}
		quit <-0
	}()
	fibonacciSelect(c,quit)
}
func fibonacciSelect(c, quit chan int) {
	x, y := 1, 1
	for {
		select {
		case c <- x:
			x, y = y, x + y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func channelTest()  {
	a := []int{7, 2, 8, -9, 4, 0}
	//無緩衝 channel,
	c := make(chan int)
	go sum(a[:len(a)/2],c)
	go sum(a[len(a)/2:],c)
	//receive from c
	x,y := <-c,<-c
	fmt.Println(x,y,x+y)

	//帶緩衝
	cb :=make(chan int,4)
	cb <- 1
	cb <- 2
	cb <- 1
	cb <- 2
	fmt.Println(<-cb,<-cb)
	fmt.Println(<-cb,<-cb)
	//for
	ccc :=make(chan int,10)
	go fibonacci(cap(ccc),ccc)
	for i :=range  ccc  {
	fmt.Println(i,"-------")
	}
}

func fibonacci(n int, c chan int) {
	x, y := 1, 1
	for i := 0; i < n; i++ {
		c <- x
		x, y = y, x + y
	}
	close(c)
}
func sum(a []int,c chan int)  {
	total :=0
	for _,v :=range  a{
		total +=v
	}
	//send to c
	c <- total
}
func gogo()  {
	fmt.Println("goroutine----------------")
	fmt.Println("gogogo")
	go saysay("hello")
	go saysay("he11")
	saysay("world")
	fmt.Println("hehe")
}

func saysay(ss string)  {

	for i := 0; i < 3; i++ {
		runtime.Gosched()
		fmt.Println(ss)
	}
}

func baseTypeTest()  {
	fmt.Println("baseTypeTest-----------")
	println("枚舉",HEHE,WHITE,BLACK)
	a :=1
	b :="1"
	c :=[]int{1,2,3}
	ccc :=c[1:2]
	var cc =c[1:2]
	d :=make(map[string]int)
	e :=map[string]int{"11":2,"33":4}
	e["11"]=33
	ep :=e
	app :=&a
	*app=11
	epp :=&e
	//*epp["gg"]=11
	fmt.Println(a,b,c,cc,ccc,d,e,ep,app)
	fmt.Printf("ip 變量儲存的指針地址: %x\n", epp )
}
func gogoTest()  {
	fmt.Println("process Test---------")
	ifa :=1
	if ifa>=1 {
		fmt.Println("heheha")
	}
	if ifa=2;ifa>0{
		fmt.Println("hehe",ifa)
	}

	for i :=1; i<10 ; i++  {
		fmt.Println("haha",i)
	}
	for ifa<10{
		ifa+=1
		fmt.Println(ifa,"heheda")
		funcTest(ifa)
	}
	a :=[]int{1,2,3}
	//traverse
	for index,value :=range  a{
		fmt.Println(index,value,"=============")
	}
	for _,value :=range  a{
		fmt.Println(value,"=============")
	}
	for value :=range  a{
		fmt.Println(value,"========3333=====")
	}
}

func methodTest()  {
	fmt.Println("methodTest------------")
	fa,fb,fc :=test(1,2,3)
	fmt.Println(fa,fb,fc)
	fmt.Println(test1(11,22,33))
	test2(1,2,3,4)
	//func method
	fmt.Println()
	fmt.Println(funcmethod(22,funcmethod0))
}

func errorTest()  {
	fmt.Println("------error panic recover-----")
	testException()
	testCumstomException()
	//custom error
	fmt.Println("------custom-----")
	if result, errorMsg := Divide(100, 10); errorMsg == "" {
		fmt.Println("100/10 = ", result)
	}
	// 當除數爲零的時候會返回錯誤信息
	if _, errorMsg := Divide(100, 0); errorMsg != "" {
		fmt.Println("errorMsg is: ", errorMsg)
	}
}
func objectTest()  {
	fmt.Println("objtest----------")
	var obja hehe
	fmt.Println(obja)
	obja.name="aa"
	obja.width=111
	obja.height=22
	fmt.Println(obja)

	obbj :=hehe{}
	fmt.Println(obbj,"obbj--")
	objb :=hehe{1,2,"111"}
	fmt.Println("11",objb)
	//指針傳遞
	objc :=&objb
	objc.height=1
	fmt.Println(objc)
	fmt.Println(objb)
	//深拷貝
	objd :=objb
	objd.width=33
	fmt.Println(objd)
	fmt.Println(objb)

	obje :=hehe{width:1,height:2222}
	fmt.Println(obje)

	gggg :=heheqq{hehe{1,2,"hehe"},3,4}
	fmt.Println(gggg)
	//deep copy
	gg1 :=gggg
	gg1.hh=33
	fmt.Println(gggg,gg1)
	gg2 :=&gggg
	gg2.ww=44
	fmt.Println(gggg,gg2,*gg2,"  pp")
	fmt.Println(gggg.area(),area1(gggg))

	gg3 :=ha{gggg,1}
	fmt.Println(gg3.area())
}

// 實現 `error` 接口
func (de *DivideError) Error() string {
	strFormat := `
    Cannot proceed, the divider is zero.
    dividee: %d
    divider: 0
`
	return fmt.Sprintf(strFormat, de.dividee)
}

// 定義 `int` 類型除法運算的函數
func Divide(varDividee int, varDivider int) (result int, errorMsg string) {
	if varDivider == 0 {
		dData := DivideError{
			dividee: varDividee,
			divider: varDivider,
		}
		errorMsg = dData.Error()
		return
	} else {
		return varDividee / varDivider, ""
	}

}

func funcTest(aa int)bool  {
	fmt.Println("switch test-------------")
	a :=aa
	switch a {
	case 1:
		fmt.Println(11)
	case 2,3,4:
		fmt.Println(a)
	case 5:
		fmt.Println(a)
		fallthrough
	default:
		fmt.Println("default")
			}
	return false
}

func test(a int ,b int ,c int)(int ,int ,int){
	return 1,2,3
}
func test1(a int,b int,c int)(aa int,bb int,cc int)  {
	aa,bb,cc =a,b,c
	return  aa,bb,cc
}
//數組遍歷
func test2(a ...int)  {
	fmt.Println("traverse----------")
	defer fmt.Println("close close close")
	defer fmt.Println("close ---- close ----- close")
	fmt.Println(a)
	for i:=0;i< len(a);i++  {
		fmt.Println(a[i],"----------")
	}
	for index,value :=range  a{
		fmt.Println(index,value,"=============")
	}
	for _,value :=range  a{
		fmt.Println(value,"=============")
	}
	for value :=range  a{
		fmt.Println(value,"=============")
	}
}

func funcmethod0(a int)int  {
	return a
}

func funcmethod(a int,funct func1)bool  {
		return a>funct(a)
}
//defer panic recover
// 1、Go中沒有 try...catch...finally機制
//2、Go中用 defer panic recover來處理
func testException() {
	//func() {}()
	defer func() {
		err :=recover()
		if err !=nil{
			fmt.Println("err=",err)
			fmt.Println("send")
		}
	}()
	num1 := 10
	num2 := 0
	res := num1 / num2
	fmt.Println("res=",res)
}

//自定義異常 recover=catch
func testCumstomException(){
	defer func() {
		err :=recover()
		fmt.Println("catch  recover",err)
	}()
	err :=readConf("heheda")
	if err!=nil {
		fmt.Println("catch:",err)
		panic(err)
	}
}

func readConf(name string) error{
	if name=="config.ini" {
		return nil
	}
	return errors.New("文件名錯誤-------")
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章