Golang基礎測試

一、數字、字符串、常量

package main
import "fmt"
func main(){
	fmt.Println("----數字----")
	//uint8(別名"byte",0-255), uint16, uint32, uint64
	var a uint8 = 255
	var b byte = 255
	n1 := a + b
	//int8(-128-127), int16, int32(別名"rune"), int(默認,不能與int32互用),int64
	var c rune = 10
	var d int32 = 10
	n2 := c + d 
	//float32, float64(默認)
	var n3 = 3.14
	fmt.Println(n1)//254
	fmt.Printf("%T %T %T \n", n1, n2, n3)


	fmt.Println("----字符串----")
	str := "hallo "
	str += "world"//使用“+”拼接字符串
	//不能直接更改單個字符,拆成字節切片,修改後轉回字符串
	s := []byte(str)
	fmt.Println(s)
	s[1] = 'e'
	str = string(s)
	fmt.Println(str)
	//字符串可以切割
	str = "I like the " + str[6:]
	fmt.Println(str)


	fmt.Println("----常量----")
	//特殊常量iota,在 const關鍵字出現時將被重置爲 0,const 中每新增一行常量聲明將使 iota 計數一次
	const (
		A = iota
		B
		C string = "C"
		D
		E = iota
	)
	const F = iota
	fmt.Println(A, B, C, D, E, F)
}

二、指針

package main
import "fmt"
func main() {
   var a int = 4
   //一個指針變量通常縮寫爲ptr,空指針爲nil
   var ptr *int
   fmt.Println(ptr == nil)
   ptr = &a
   fmt.Printf("ptr類型爲%T\n", ptr)
   fmt.Println("ptr值爲", ptr)
   fmt.Printf("*ptr值爲%d\n", *ptr)
}

三、數組和切片

package main
import (
	"fmt"
)
func main() {
	fmt.Println("----數組----")
	//數組是具有相同唯一類型的一組已編號且長度固定的數據項序列
	arr1 := [3]byte{'a','b'}
	//也可以自行統計[...]byte{'a','b'},但此時固定長度爲2,則不能進行下邊賦值
	arr1[2] = 'c'
	//二維數組
	arr2 := [2][2]int{{1,2},{3}}
	arr2[1][1] = 4
	fmt.Println(arr1, arr2)


	fmt.Println("----切片----")
	//切片("動態數組",引用類型),與數組相比切片的長度是不固定的,可以追加元素
	//像一個結構體,包含了指針,長度,最大長度
	slice1 := []int{1,2}
	slice2 := append(slice1, 3)
	slice3 := slice2[1:]
	fmt.Println(slice1,slice2,slice3)
	fmt.Println(cap(slice1))
	//使用make形式,第二個參數代表初始化2個默認成員,第三個參數表示最大成員數(可省略)。
	slice4 := make([]int, 2, 3)//2個成員
	slice5 := append(slice4, 67373)//3個成員,地址和slice4相同
	slice6 := append(slice5, 67373)//超出,重新分配地址
	fmt.Println(len(slice4),cap(slice4),slice4,slice5)
	fmt.Printf("%p %p %p \n",slice4,slice5, slice6)
	//未指定長度的切片等於nil
	var slice7 []int
	fmt.Println(slice7 == nil)
}

四、Map集合

package main
import "fmt"
func main() {
	//初始化,也可以使用make
	m1 := map[string]int{"a": 1}
	//添加鍵
	key := "b"
	m1[key] = 2
	//map爲引用類型,m1和m2同一個地址
	m2 := m1
	m2["c"] = 3
	fmt.Println(m1)
	//遍歷
	for key, val := range m1 {
		fmt.Printf("key=%s,val=%d\n", key, val)
	}
	//刪除
	delete(m1, "c")
	fmt.Println(m2)
}

五、Struct結構體

package main
import "fmt"
type Human struct{
	Name string
	Age int
}
//組合,相當於類繼承
type Student struct{
	Human
	Number int
}
func main(){
	me := Student{
		Human : Human{ Name: "abc"},
		Number: 67373,//換行結束時此處必須有逗號
	}
	//兩種形式皆可獲得,未賦值Age數字類型默認爲0
	me.Age = 1
	me.Human.Age = 2
	fmt.Println(me)

	//匿名結構體,臨時使用
	his := struct{
		name string
		age uint8
	}{"his",34}
	fmt.Println(his)
}

六、函數

package main
import "fmt"

//多個返回值
func fn1(c int) (d int,e int){
	d,e = c + 1, c + 2
	return 
}
func fn2(c int) (int, int){
	return c + 1, c + 2
}
//不定參數生成反轉數組
func fn3(arg ...int) []int{
	length := len(arg)
	s := make([]int, length)
	for i := 0; i < length; i++ {
		s[i] = arg[length - i - 1]
	}
	return s
}
//專有函數
type Me struct{

}
func (this *Me) say (str string) error {
	fmt.Println(str)
	return nil
}

func main() {
	c := 1
	//多返回值
	d,e := fn1(c)
	f,g := fn2(c)
	fmt.Println(d, e, f, g)
	//不定參數
	s := fn3(1,2,3,4)
	fmt.Println(s)
	//say不能直接調用
	me := Me{}//new(Me)
	me.say("只能我能調用say方法")
}

七、接口

package main
import "fmt"
func main() {
	//空接口可以傳任何類型
	type Element interface{}
	//一個空接口類型的切片的值可以是任意類型
	list := []Element{1,"Hello",'e'}
	fmt.Println(list)
	//斷言類型
	val,ok := list[0].(int)
	fmt.Println(val,ok)
	
	//使用接口類型
	var phone Phone = new(Huawei)//這裏必須取址,等同&Huawei{}
	phone.call()
}

//定義接口
type Phone interface {
	call()
}
//定義結構體
type Huawei struct {

}
//接口實現方法
func (huawei *Huawei) call() {
	fmt.Println("我用華爲打電話")
}

八、併發goruntine

package main 
import (
	"fmt"
	"runtime"
)
func main() {
	fmt.Printf("CPU數量%d \n",runtime.NumCPU())
	runtime.GOMAXPROCS(3)//設置可以並行計算的CPU核數,返回之前的值

	for i := 0; i < 10; i++ {
		fmt.Println(i)//固定順序,被gorutine穿插
		go func(i int){
			fmt.Printf("goruntine%d\n", i)
		}(i)//輸出的數量不固定,順序不固定
	}
}

九、chan通道

package main
import (
    "fmt"
	"time"
)
//通道可以聲明接收或者發送類型
// type Sender chan<- int
// type Receiver <-chan int
func main() {
	//默認非緩存阻塞的,即第二個參數默認0.
	//設置緩存數量,可以直接寫入,(再直接寫入會報錯),其後的可以通過goruntine寫入
	c := make(chan int, 2)
	c <- 1
	c <- 2
	go func(c chan<- int) {
		for i := 3; i < 6; i++ {
			c <- i
			fmt.Println("發送",i)
		}
		close(c)
	}(c)
	//1,2可以直接讀取,goruntine不一定這時候有沒有發送,所以此時等待,接收到便讀取,直到close
	for i := range c {
		fmt.Println("接收", i)
	}
	// 讓main函數執行結束的時間延遲1秒,
	// 以使上面兩個代碼塊有機會被執行。
	time.Sleep(time.Second)
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章