專科 java轉go 翱翔之路(二)基礎語法:匿名組合,方法,接口,map,json,異常處理,channel管道,select用法

2.4 面向對象編程

2.4.1匿名組合


type Person struct {
	id   int
	name string
	age  int
}

type Student struct {
	Person //只有類型 沒有名字,匿名字段 繼承了person的成員
	garde  string
	class  string
}

2.4.1.2 定義類,賦值,修改

	//定義類
	var per1 Student = Student{Person{1, "生活", 18}, "初中", "初一"}
	fmt.Println("per1", per1)
	//自動推導類型
	per2 := Student{Person{1, "生活", 18}, "初中", "初一"}
	fmt.Printf("per2 %v\n", per2)
	//單獨複製
	per3 := Student{class: "初一"}
	fmt.Printf("per3 %v\n", per3)
	per4 := Student{Person: Person{id: 5}, class: "初一"}
	per4.name = "sss"
	per4.Person = Person{5, "aaa", 22}
	fmt.Printf("per4 %v\n", per4)

2.4.1.3 匿名字段追加

//非結構匿名字段
type addColum string
func main() {
	per2 := Student{Person{1, "生活", 18}, "初中", "初一", "追加字段"}
	fmt.Printf("per2 %v\n", per2)//per2 {{1 生活 18} 初中 初一 追加字段}
}

2.4.1.4 地址匿名字段追加

//非結構匿名字段
type addColum string

type Person struct {
	id   int
	name string
	age  int
}

type Student struct {
	*Person //只有類型 沒有名字,匿名字段 繼承了person的成員
	garde   string
	class   string
	addColum
}

func main() {
	per2 := Student{&Person{1, "生活", 18}, "初中", "初一", "追加字段"}
	fmt.Printf("per2 %v\n", per2)
	fmt.Println(per2.id, per2.name, per2.age, per2.garde, per2.class)
	var per3 Student
	per3.Person = new(Person)
	per3.addColum = "append"
	per3.id = 5
	per3.name = "sss"
	fmt.Println(per3.id, per3.name, per3.age, per3.garde, per3.class)
}

2.4.2方法

2.4.2.1 定義

//面向對象,方法:給某個類型綁定一個函數
type long int

//tmp叫接受者,接受者傳遞的一個參數
func (tmp long) Add02(other long) long {
	fmt.Println("tmp =", tmp)//1
	return tmp + other

}

func main() {
	//定義一個變量
	var test long = 1
	//調用方法格式 :變量名.函數
	r := test.Add02(3)
	fmt.Println("r =", r)//4

}

2.4.2.2 賦值,輸出


//輸出函數
func (per Person) pringInfo() {
	fmt.Println("per =", per)
}

//賦值函數
func (per Person) setInfo(a int, b string, c int) {
	per.id = a
	per.name = b
	per.age = c

	fmt.Println("per =", per)
}

func main() {
	per1 := Person{1, "小三", 20}
	per1.pringInfo()
	per1.setInfo(2, "小三的小三", 21)

}

2.4.2.3 值傳遞與引用傳遞

type Person struct {
	id   int
	name string
	age  int
}

//賦值函數
func (per Person) setInfo(a int, b string, c int) {
	per.id = a
	per.name = b
	per.age = c

	fmt.Printf("per = %v\n", per)//per = {3 修改 22}
}

//引用傳遞
func (per *Person) setInfoPoint(a int, b string, c int) {
	per.id = a
	per.name = b
	per.age = c

	fmt.Printf("per = %v\n", per)//per = &{4 修改 32}
}

func main() {
	per1 := Person{1, "小三", 20}
	per1.setInfo(3, "修改", 22) //引用傳遞
	fmt.Println(per1)//{1 小三 20}
	per2 := Person{2, "小三的小三", 21}
	per2.setInfoPoint(4, "修改", 32) //值傳遞
	fmt.Println(per2) //{4 修改 32}

}

2.4.2.4 繼承傳遞


type Person struct {
	id   int
	name string
	age  int
}

type Student struct {
	Person
	garde string
}
//輸出函數
func (per Person) pringInfo() {
	fmt.Println("per =", per)
}

func main() {
	//繼承
	stu := Student{Person{5, "小三5", 25}, "s"}
	stu.pringInfo()
	fmt.Println(stu)

}

2.4.2.5 方法值

	stu := Student{Person{5, "小三5", 25}, "s"}
	stu.pringInfo()
	//方法值 保存方式入口地址
	pFunc := stu.pringInfo //這個就是方法值,調用函數時,無需再傳遞接受者
	pFunc() //等價於 stu.pringInfo()

2.4.2.5 方法表達式

	//方法表達式
	f := (*PePerson).setInfoPoint
	f(&stu) //等價於 stu.setInfoPoint()

	f1 := (PePerson).setInfo
	f1(stu) //等價於 stu.setInfo()

	fmt.Println(stu)

2.4.3接口

2.4.3.1 定義

//定義接口
type inter interface {
	say()
}

//studnt實現了say方法
func (tmp *Teacher) say() {

	fmt.Printf("Studnt %s\n", tmp.zz)
}

func main() {
	var i inter
		//只要實現 該接口,就可以給這個接口賦值
	s := &Teacher{"是啥"}
	i = s
	i.say()//Studnt 是啥
}

2.4.3.2 繼承實現

type inter interface {
	say()
}
type inter1 interface {
	inter
	say1()
}

//studnt實現了say方法
func (tmp *Teacher) say() {

	fmt.Printf("Studnt %s\n", tmp.zz)
}

//studnt實現了say1方法
func (tmp *Teacher) say1() {

	fmt.Printf("Studnt %s\n", tmp.zz)
}

func main() {
	var i inter1
	//只要實現 該接口,就可以給這個接口賦值
	s := &Teacher{"是啥"}
	i = s
	i.say()
	i.say1()
}

2.4.3.3 接口轉換

	var i1 inter1 //超集
	i1 = &Teacher{"是啥"}
	var i inter //子集

	i = i1 //可以 超集可以轉換爲子集

	i.say()

2.4.3.4 空接口

	i := make([]interface{}, 3)

	i[0] = 1
	i[1] = "ss"

	for index, data := range i {

		if value, ok := data.(int); ok == true {
			fmt.Printf("index [%v] ,x[%d]\n", index, value)
		}

	}


2.5 異常處理,字符串

2.5.1錯誤接口(error)

	err1 := fmt.Errorf("%s", "no error")
	fmt.Println(err1)
	err2 := errors.New("錯誤")
	fmt.Println(err2)

2.5.1.1錯誤接口的應用

func MyDiv(a, b int) (result int, err error) {
	err = nil
	if b == 0 {
		err = errors.New("B不能爲0")
	} else {

		result = a / b
	}
	return

}

func main() {

	val, err := MyDiv(1, 0)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(val)
	}

}

2.5.2函數程序中斷(panic)

func test() {
	//導致程序中斷
	panic("this is a panic")
}

2.5.3函數程序(recover)

func test1() {

	defer func() {
		//err是該函數默認返回值
		if err := recover(); err != nil {
			fmt.Println(err)
		}

	}() //()調用此函數
}

2.5.4字符串函數的使用

	fmt.Println(strings.Contains("abcdefg", "abc")) //true

	arr := []string{"abc", "hello", "arr"}
	fmt.Println(strings.Join(arr, "@")) //abc@hello@arr

	fmt.Println(strings.Index("abcdefg", "b")) //1

	arrStr := "abc@hello@arr"
	fmt.Println(strings.Split(arrStr, "@")) //[abc hello arr]

2.5.5 strconv包

	arr1 := make([]byte, 0, 1024)
	arr1 = strconv.AppendBool(arr1, true)
	//整數轉字符串
	arr2 := strconv.Itoa(6666)
	fmt.Println(arr2)
	//其他類型轉換爲字符串
	var str string
	str = strconv.FormatBool(false)
	fmt.Println(str)

2.6 json

2.6.1 結構體轉json

import "fmt"
import "encoding/json"

//首字母必須大寫
type Student struct {
	Id    int    `json:"-"`    //此字段不會輸出
	Name  string `json:"name"` //返回時返回指定字段
	Sub   []string
	IsOk  bool  `json:",string"` //返回字符串
	Price float64
}

func main() {

	stu := Student{1, "小明", []string{"go", "java", "php"}, true, 50.00}
	fmt.Println(stu)
	//json轉義
	buf, err := json.Marshal(stu)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(buf) //[123 34 73 100 34 58 49 44 34 78 97 109 101 34 58 34 229 176 143 230 152 142 34 44 34 83 117 98 34 58 91 34 103 111 34 44 34 106 97 118 97 34 44 34 112 104 112 34 93 44 34 73 115 79 107 34 58 116 114 117 101 44 34 80 114 105 99 101 34 58 53 48 125]
	fmt.Println(string(buf))
}

2.6.2 map轉json


	map1 := make(map[string]interface{}, 4)
	map1["id"] = 5
	map1["name"] = "實時"

	buf, err := json.MarshalIndent(map1, "", " ")
	fmt.Println(string(buf))
	fmt.Println(err)

2.6.3 json轉實體

func main() {

	jsonBuf := `
	{
	 "id": 5,
	 "name": "實時"
	}`

	var stu1 Student

	json.Unmarshal([]byte(jsonBuf), &stu1)

	fmt.Println(stu1)//{0 實時 [] false 0}

}

2.6.4 json轉map

func main() {

	
	jsonBuf := `
	{
	 "id": 5,
	 "name": "實時"
	}`

	map2 := make(map[string]interface{}, 4)
	json.Unmarshal([]byte(jsonBuf), &map2)
	fmt.Println(map2)
	//斷言 判斷類型
	var str string
	for key, value := range map2 {
		switch data := value.(type) {
		case string:
			str = data
			fmt.Printf("map[%s]的值類型爲string", key)
		case []interface{}:
			fmt.Printf("map[%s]interface{}", key)

		}
	}

}

2.7 goroutine併發並行

2.7.1 demo

import "fmt"
import "time"

func newWork() {
	for {
		fmt.Println("this is newWork")
		time.Sleep(1000)
	}
}

func main() {
    //設置並行處理器
	num := runtime.GOMAXPROCS(1)
	fmt.Println(num)
	//goroutine
	go newWork() //新建一個協程任務
	for {
		fmt.Println("this is mainWork")
		time.Sleep(1000)
	}
}

2.7.2主協程退出,子協程也退出

func main() {
	//主協程退出了,其它子協程也要跟着退出
	go func() {
		for {
			fmt.Println("this is goroutine")
		}
	}()

	i := 0
	for {
		i++
		fmt.Println("this is mainFor")
		time.Sleep(1000)
		if i > 2 {
			break
		}
	}

}

2.7.3 Goschedr讓出調度資源 Goexit 終止

import "runtime"
func main() {
    //設置並行處理器
	num := runtime.GOMAXPROCS(1)
	fmt.Println(num)
	//Goschedr
	go func() {

		for j := 0; j < 2; j++ {
			fmt.Println("this is goroutine")
			runtime.Goexit() //終止所有協程
		}
	}()

	i := 0
	for {
		i++
		fmt.Println("this is mainFor")
		runtime.Gosched() //讓出時間片,先讓其他協議執行
		if i > 2 {
			break
		}
	}

}

2.7.4

2.7.4.1 Demo channel管道

//創建一個無緩存的channel
var ch = make(chan int)

func printWork(val string) {

	fmt.Println(val)
	fmt.Println(val)
	fmt.Println(val)
	fmt.Println(val)
	fmt.Println(val)

}

func per(sendv string) {
	printWork(sendv)
	ch <- 666 //給管道協數據,發送
}

func per1(sendv string) {
	<-ch //從管道取數據,接收,如果管道沒有數據阻塞
	printWork(sendv)
}

func main() {

	go per("per1")
	go per("per2")

	for {

	}

	// per2
	// per2
	// per2
	// per2
	// per1
	// per1
	// per1
}

2.7.4.2 channel 特點

func main() {
var ch3 chan<- float64 //ch3是單向channel 只用於讀寫float64數據
ch := make(chan int)
	//雙向隱轉單向
	var writhCh chan<- int = ch //只能寫,不能讀
	var readCh <-chan int = ch  //只能讀,不能寫
	
	writh <-666 //寫
	<-readch//讀
	

	//單向無法轉換爲雙向
	var ch2 chan int = writhCh
	}

2.7.4.3 channel 應用

//生產者  只能寫,不能讀
func product(out chan<- int) {

	for i := 0; i < 10; i++ {
		out <- i * i
	}
	close(out)

}

//消費者 只能讀,不能寫
func consumer(in <-chan int) {

	for num := range in {
		fmt.Println("consumer=", num)
	}

}

func main() {
	//創建一個雙向通道
	ch := make(chan int)

	//生產者
	go product(ch)
	//消費者
	consumer(ch)

}

2.7.4.4 定時器

import "time"

func main() {
	//只執行一次
	timer := time.NewTimer(2 * time.Second)
	//重複執行
	timer1 :=time.NewTicker(2 * time.Second)
	fmt.Println(time.Now())

	t := <-timer.C
	fmt.Println(t)

	timer.Reset(1 * time.Second) //重新設置
	timer.Stop()                 //定時器停止
	//2020-06-13 14:06:05.8875131 +0800 CST m=+0.008002001
	//2020-06-13 14:06:07.8881753 +0800 CST m=+2.008664201
}

2.7.4.5 select用法

func main() {

	ch := make(chan int)
	quit := make(chan bool)

	//新開一個協程
	//讀數據
	go func() {
		for {
			select {
			case num := <-ch:
				fmt.Println("num = ", num)
			case <-time.After(3 * time.Second):
				fmt.Println("超時")
				quit <- true
			}

		}

	}() //自調用
	//寫數據
	for i := 0; i < 5; i++ {
		ch <- i
		time.Sleep(time.Second)
	}
	<-quit

	fmt.Println("程序結束")

}






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