<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      go基礎學習

      壞境

      安裝SDK

      下載地址

      windows 安裝

      可以直接下載安裝msi 不需要配置壞境變量默認配置好了
      zip 里面包含源碼,但是需要配置壞境變量

      liunx安裝SDK

      
         wget https://dl.google.com/go/go1.20.2.linux-amd64.tar.gz
         tar -C /usr/local -xzf go1.20.2.linux-amd64.tar.gz
         cd /usr/local
         cd go # 發現里面右go目錄
         ## 可以看到結果
         bin/go version  #
      

      配置 GOROOT 和 PATH壞境變量
      GOROOT: export GOROOT=/usr/local/go
      PATH : export PATH=$PATH:$GOROOT/bin:$GOBIN
      vim /root/.profile 最后加入到 etc/.profile
      將2個環境變量加入到最下面

      export GOROOT=/usr/local/go    
      export PATH=$PATH:$GOROOT/bin:$GOBIN  
      

      刷新壞境變量
      source /etc/profile
      root source /root/.profile

      第一次使用問題

      go mod init 之類的錯誤 可以執行下命令
      go env -w GO111MODULE=off

      壞境變量配置

      1. GOROOT 指定sdk 路徑 新建系統壞境變量 GOROOT = go的安裝目錄C:\Program Files\Go
      2. Path 添加sdk bin目錄 修改PATH ;%GOROOT%/bin
      3. GOPATH 工作目錄

      Path 環境變量添加只需要 引用 sdk的變量 %sdk變量%/bin

      常量

      簡單常量

      const Pi=3.1415926
      const abc="abc"
      

      聲明賦值常量

      const beef, two, sundsewew = "eat", 2, "veg"
      const (monday,tuesday,wenday,t=1,2,3,4);
      

      用作枚舉常量

      const (
          Unknown = 0
          Female = 1
          Male = 2
      )
      

      枚舉簡寫

      iota用法  
      
              package main
              import "fmt"
              func main() {
      
                  const (
                      a = iota   //0
                      b          //1
                      c          //2
                      d = "ha"   //獨立值,iota += 1
                      e          //"ha"   iota += 1
                      f = 100    //iota +=1
                      g          //100  iota +=1
                      h = iota   //7,恢復計數
                      i          //8
                  )
                  fmt.Println(a,b,c,d,e,f,g,h,i)
              }
      
      iota,特殊常量,可以認為是一個可以被編譯器修改的常量。  
      iota 是0 ,后面都會依次,0,1,2,簡單來說每次遇見const iota 都會重置0  
      
      const (
          a=iota
          b
          c
      )
      

      某個類型作為枚舉常量的類型

      type Color int
      	const (
      		RED Color = iota // 0
      		ORANGE // 1
      		YELLOW // 2
      		GREEN // ..
      		BLUE
      		INDIGO
      		VIOLET // 6
      	)
      

      變量

      變量聲明了一般必須使用
      小寫開頭的變量外部包是沒法訪問的(私有的),只有首字母大寫才可以訪問(公開的)
      
      var a int
      var b bool
      var c string
      var (a1 int,b1 bool,c1 string)
      
      當變量聲明后就會有默認值 int 0,float 0.0  bool false   string 為空字符串,  指針為 nil, 所有的內存在go中都需要經過初始化, 如果一個變量在函數體外定義,則它就是個全局變量,函數體內聲明局部變量  簡寫 a:=1    不支持函數外部定義
      
      var goos string = runtime.GOOS
          fmt.Printf("The operating system is: %s\n", goos)
      	// path  局部變量
          path:= os.Getenv("PATH")  
          fmt.Printf("Path is %s\n", path)
      

      // 局部變量和全局變量 名稱相同, 編譯器會采用就近原則

      值類型

      • 內存地址都是以16進制表示
      • int、float、bool、string 都是值類型,使用這些類型的變量直接指向內存中的值,像數組復合類型也屬于值類型
      • i=j 是將i的值拷貝了一分給了j
      • 通過&i 可以獲取到內存地址,值類型變量的值都存在棧中
      • 引用類型,變量存的是一個地址,
      • 內存的地址被稱為指針,
      • 指針指向的內存都是連續的,這也是計算效率最好的一種存儲形式。每個字節指向了下一個字節的地址
      • 引用類型賦值,只是地址拷貝

      字符串

      • 不可變:一旦賦值就不能再修改了
      • 表示方式
        • 雙引號 :一般常規的字符串,特殊字符串需要轉移
        • 反引號 : `` 直接原分不動的輸出
      • 拼接方式:
        • 直接用+ 拼接,或者+= 適用于短的字符串拼接
        • 多行拼接 可以換行,換行后,需要將+放在上一行

      解釋字符串

      • \n:換行符
      • \r:回車符
      • \t:tab 鍵
      • \u 或 \U:Unicode 字符
      • \:反斜杠自身

      非解釋字符串

      字符串就是一串固定長度的字符連接起來的字符序列。Go 的字符串是由單個字節連接起來的。Go 語言的字符串的字節使用 UTF-8 編碼標識 Unicode 文本。
      

      打印

      通用

          %v	值的默認格式表示
          %+v	類似%v,但輸出結構體時會添加字段名
          %#v	值的Go語法表示
          %T	值的類型的Go語法表示
          %%	百分號
      

      整數

          %b	表示為二進制
          %c	該值對應的unicode碼值
          %d	表示為十進制
          %o	表示為八進制
          %q	該值對應的單引號括起來的go語法字符字面值,必要時會采用安全的轉義表示
          %x	表示為十六進制,使用a-f
          %X	表示為十六進制,使用A-F
          %U	表示為Unicode格式:U+1234,等價于"U+%04X"
      

      布爾

          %t	單詞true或false
      

      浮點數與復數的兩個組分

          %b	無小數部分、二進制指數的科學計數法,如-123456p-78;參見strconv.FormatFloat
          %e	科學計數法,如-1234.456e+78
          %E	科學計數法,如-1234.456E+78
          %f	有小數部分但無指數部分,如123.456
          %F	等價于%f
          %g	根據實際情況采用%e或%f格式(以獲得更簡潔、準確的輸出)
          %G	根據實際情況采用%E或%F格式(以獲得更簡潔、準確的輸出)
      

      字符串和[]byte

          %s	直接輸出字符串或者[]byte
          %q	該值對應的雙引號括起來的go語法字符串字面值,必要時會采用安全的轉義表示
          %x	每個字節用兩字符十六進制數表示(使用a-f)
          %X	每個字節用兩字符十六進制數表示(使用A-F)    
      

      指針:

          %p	表示為十六進制,并加上前導的0x    
      

      類型與運算

      整數與浮點數

      go沒有float 和doule 類型,只有 float32 和 float64

      • 整數:

        • int8(-128 -> 127)
        • int16(-32768 -> 32767)
        • int32(-2,147,483,648 -> 2,147,483,647)
        • int64(-9,223,372,036,854,775,808 -> 9,223,372,036,854,775,807)
      • 無符號整型

        • uint8(0 -> 255)
        • uint16(0 -> 65,535)
        • uint32(0 -> 4,294,967,295)
        • uint64(0 -> 18,446,744,073,709,551,615)
      • 浮點型(IEEE-754 標準):

        • float32(+- 1e-45 -> +- 3.4 * 1e38)
        • float64(+- 5 1e-324 -> 107 1e308)

      整數是計算最快的一種類型

      類型轉換

      Sprint

          package main
          import "fmt"
      
          func main() {
      
              var num1 int =99
              var num2 float64 =23.5566
              var b bool =true
              var str string
              
              //Sprintf根據format參數生成格式化的字符串并返回該字符串。
              str=fmt.Sprintf("%d",num1)
              //%T 打印類型
              fmt.Printf("類型 %T  str=%v \n",str,str)
              // %f 有小數部分但無指數部分,如123.456
              str=fmt.Sprintf("%f",num2)
              fmt.Printf("類型 %T  str=%v \n",str,str)
              //%t	單詞true或false
              str=fmt.Sprintf("%t",b)
              fmt.Printf("類型 %T  str=%v \n",str,str)
          }
      
      

      strconv

      package main
      import "fmt"
      import "strconv"
      
      func main() {
      
      	var num1 int =99
      	var num2 float64 =23.5566
      	var b bool =true
      	var str string
      	
      	str=strconv.FormatInt(int64(num1),10)
      	fmt.Printf("類型 %T  str=%q \n",str,str)
      	// f 格式,10 保留位數,64 是float64
      	str=strconv.FormatFloat(num2,'f',10,64)
      	fmt.Printf("類型 %T  str=%q \n",str,str)
      
      	str=strconv.FormatBool(b)
      	fmt.Printf("類型 %T  str=%v \n",str,str)
      
      }
      

      Parse

      他一般有 ParseBool ParseInt ParseFloat 等
      返回2個值 接受方式用 n1,_=

      指針

      • 獲取變量地址用&
          var i int=10
          fmt.Println("i的地址是",&i)
        ``
        
        
      package main
      import "fmt"
      // import "strconv"
      
      func main() {
      	var i int=10
      	fmt.Println("i的地址是",&i)
      
      	//p是一個指針變量, 類型為*int p本身值是 &i
      	// p 存儲了一個地址  0xc00000e0a8  就是i的地址,這個地址指向了i的空間
      	var p *int =&i
      	fmt.Printf("p=%v\n",p)
      	fmt.Printf("p的地址=%v",&p)
      	// 通過p 取出 i的值 10
      	fmt.Printf("p指向的值是=%v \n",*p)
      	// 修改了i的值
      	*p=20
      
      	fmt.Printf("p指向的值是=%v \n",*p)
      	fmt.Println(i)
      
      }
      
      

      獲取用戶的輸入

      fmt.Scanln()

      package main
      import "fmt"
      // import "strconv"
      
      func main() {
      	var name string
      	var age byte
      	var sal float32
      	
      	fmt.Println("請輸入姓名")
      	fmt.Scanln(&name)
      
      	fmt.Println("請輸入年紀")
      	fmt.Scanln(&age);
      
      	fmt.Println("請輸入薪水")
      	fmt.Scanln(&sal);
      
      	fmt.Printf("姓名%v \n 年紀%v \n  薪水%v \n ",name,age,sal );
      
      }
      
      

      fmt.Scanf()

      package main
      import "fmt"
      // import "strconv"
      
      func main() {
      	var name string
      	var age byte
      	var sal float32
      
      	fmt.Println("請依次輸入,姓名,年紀 薪水,用空格隔開")
      	//接受數據的類型可以參考文檔
      	fmt.Scanf("%s %d %f",&name,&age,&sal)
      	fmt.Printf("姓名:%v 年齡:%v 薪資:%v ",name,age,sal)
      }
      
      

      運算

      除法運算

      package main
      import "fmt"
      
      func main() {
      	var n1 float32 =10/4
      	//這里 因為都是整數相除的,那么除后會去掉小數部分,保留整數部分,
      	fmt.Println(n1)  // 結果是2
      	//如果要保留小數需要  10.0/4
      	var n2 float32 =10.0/4
      	fmt.Println(n2)  // 結果是2
      }
      

      求模

      公式 a%b =a-a/b*b

      	fmt.Println("10%3=",10%3,"     10-10/3*3=",10-10/3*3) //1
      	fmt.Println("-10%3=",-10%3,"     -10-(-10)/3*3=",-10-(-10)/3*3) //-1
      	fmt.Println("10%-3=",10%-3,"     10-10/-3*-3=",10-10/-3*-3)   //1
      

      流程控制

      if else 語句

      go 語言中,大括號,有時候是不能換行的,換行就會報錯
      go 中的if 一般是不需要加括號的,除非是,if(a>0 && a<10) || a==90 其實這里的括號也不是給if的加的,是給條件加的

      package main
      import "fmt"
      func main() {
      	var age int 
      	fmt.Println("請輸入年齡")
      	fmt.Scanln(&age)
      	if age>18 && age<=60 { // 這個大括號不能換行的,換行就會報錯的
      		fmt.Println("成年人")
      	}else if age>60{
      		fmt.Println("老年人");
      	}else{
      		fmt.Println("未成年人");
      	}
      }
      

      swich

      swich 語句后面是不需要加 break的
      case :后面可是常量,也可以是個函數,也可以運算

      package main
      import "fmt"
      func main() {
      	var key byte
      	fmt.Println("請輸入字符串a,b,c,d,e");
      	fmt.Scanf("%c",&key);
      
      	switch key {
      	case 'a':
      		fmt.Println("======>a");
      	case 'b':
      		fmt.Println("======>b");
      	case 'c':
      		fmt.Println("======>c");
      	case 'd':
      		fmt.Println("======>d");
      	case 'e':
      		fmt.Println("======>e");
      	case 'f','g','h':
      		fmt.Println("======>其他輸入");
      	default:
      		fmt.Println("輸入有誤");
      	}
      }
      
      
      package main
      import "fmt"
      func main() {
      	var  age int =10
      	switch  {  //也可以 switch age:=10;{}
      	case age==10:
      		fmt.Println("10")
      	case age>10:
      		fmt.Println("大于10")
      	}
      }
      
      
      

      switch 穿透 fallthrought

      package main
      import "fmt"
      func main() {
      	var  age int =10
      	switch age  {
      	case 10:
      		fmt.Println("10")
      		fallthrough  //默認只能穿透一層
      	case 20:
      		fmt.Println("20")
      		fallthrough  //默認只能穿透一層
      	case 30:
      		fmt.Println("30")
      	case 40:
      		fmt.Println("40")
      
      	}
      }
      
      

      循環

      for

      例子

      package main
      import "fmt"
      func main() {
      	for i := 0; i < 10; i++ {
      		fmt.Println("您好!",i)
      	}
      }
      
      

      格式
      循環初始,循環條件,循環迭代
      順序

      1. 初始化i=0
      2. 條件 i<10
      3. 如果為真,執行fmt.Println
      4. 執行迭代,i++
      5. 反復執行,直到條件為假 退出

      for 第二種寫法

      和第一種寫法其實一樣

      package main
      import "fmt"
      func main() {
      	i:=0
      	for  i < 10 {
      		fmt.Println("您好!",i)
      		i++
      	}
      }
      

      for 第三種寫法

      package main
      import "fmt"
      func main() {
      	// 配合break 用法
      	for {
      		fmt.Println("您好!",i)
      	}
      }
      

      字符串遍歷

      func main() {
      	var str string="hello world!"
          //str2=[]rune(str)  // 將下面的str 改成str2  這個就是切片
      	for i := 0; i < len(str); i++ {
      		fmt.Printf("%c \n",str[i]);
      	}
      }
      
      

      如果 str字符串包含中文,就會出問題,亂碼,
      傳統對字符串的便利是按照字字節來遍歷的,而一個漢字再utf8 中包含3個字節
      解決的方法,需要將,str轉換成切片, 或者用 for-range

      for-range

      func main() {
      	var str string="hello world!"
      	for i := 0; i < len(str); i++ {
      		fmt.Printf("%c \n",str[i]);
      	}
      
      	str="abcd西安"
      	for index, val := range str {
      		fmt.Printf("index=%d, val=%c \n",index,val)
      	}
      }
      
      

      結果

      本地圖

      循環案例

      打印金字塔

      
      // 打印金字塔
      // 	   *        1-> 1個*    i+(i-1) -> 2i-1    空格 2   3-1   空格數=n-層
      //    ***		2-> 3個*	 2*2-1=3			  1	 3-2
      //   *****		3-> 5個*	 2*3-1=5			  0   3-3
      func main() {
      	var count int =30
      	for i := 1; i <= count; i++ {
      		// 打印空格
      		for k := 0; k < count-i; k++ {
      			fmt.Print(" ");
      		}
      		//打印星星
      		xx:=2*i-1
      		for j := 1; j <= xx; j++ {
      			//fmt.Print("*"); // 實心金字塔
      			if j==1 || j==xx { // 空心金字塔
      				fmt.Print("*");  //第一個和最后一個打印星星
      			}else{
      				if i==count{ // 如果是最后一行
      					fmt.Print("*");
      				}else{
      					fmt.Print(" ");
      				}
      			}
      		}
      		fmt.Println(); // 換行
      	}
      }
      
      
      

      九九乘法表

      func main() {
      
      	for i := 1; i <= 9; i++ {
      		for j := 1; j <= i; j++ {
      			fmt.Printf("     %d x %d = %d",j,i, i*j);
      		}
      		fmt.Println()
      	}
      }
      

      隨機數

      package main
      import (
      	"fmt"
      	"math/rand"
      	"time"
      )
      
      func main() {
      
      	var count int =0
      	for  {
      		//生成100次 退出
      		if count==100 {
      			break
      		}
      		//t:=time.Now().Unix()  // 返回當前的時間戳
      		//fmt.Println(t)
      		rand.Seed(time.Now().UnixNano())// 納秒 以當前時間作為隨機種子  重復的幾率還是很大
      		n:=rand.Intn(100)+1  // 生產1到100 的隨機數
      		fmt.Println(n)
      		count++
      	}
      
      	
      }
      
      
      

      break continue

      和C#里面的差不多

      break 直接跳出循環,結束了
      continue 跳出當次循環,然后進行下一次,

      goto

      package main
      import (
      	"fmt"
      
      )
      
      func main() {
      
      	var n int =4
      	fmt.Println("1")
      	fmt.Println("2")
      	if(n>3){
      		goto Lable
      	}
      	fmt.Println("3")
      	fmt.Println("4")
      	fmt.Println("5")
      	Lable:
      	fmt.Println("6")
      	fmt.Println("7")
      }
      
      

      return

      結束方法 函數。

      函數

      實例

      package main
      import (
      	"fmt"
      )
      
      func main() {
      
      	result:=cal(2.3,2.7,'+')
      	fmt.Println("result=",result)
      }
      
      func cal(n1 float64,n2 float64,o byte ) float64{
      
      	switch o {
      		case '+':
      			return n1+n2
      		case '-':
      			return n1-n2
      		case '*':
      			return n1*n2
      		case '/':
      			return n1/n2
      		default:
      			fmt.Println("不支持的計算")
      		return -99999
      	}
      
      } 
      

      返回多個參數的函數

      package main
      import (
      	"fmt"
      	
      )
      
      func main() {
      	fmt.Println("返回多個參數的");
      	
      	// res1,res2:=A(2,3)
      	// fmt.Println("sum=",res1)
      	// fmt.Println("ss=",res2)
      
      	_, res2:=A(2,3)
      	fmt.Println("ss=",res2)
      }
      
      func A(a int,b int)(int,int){
      	sum:=a+b
      	ss:=a*b
      	return sum ,ss
      }
      
      
      

      函數的引用傳值方式

      上面的函數傳值 都是以值傳值的方式,通過拷貝的方式

      package main
      import (
      	"fmt"
      )
      
      func main() {
      	a:=4
      	A(&a) // 直接傳了a的地址
      	fmt.Println("main a=",a);
      }
      // a的指針
      func A(a *int ) {
      	*a++   // 根據地址找到修改了
      	fmt.Println("A() a=",*a);
      }
      

      將函數當作參數傳遞

      package main
      import (
      	"fmt"
      )
      
      func main() {
      	
        s:=SS(sum,20,40)
         fmt.Println("s=",s);
      
      }
      
      func SS(dd func(int,int)int, a int,b int) int{
      	return dd(a,b)
      }
      
      func sum(a int,b int ) int {
      	return a+b
      }
      
      

      自定義類型

      我們可以給類型取別名

      demo1

      package main
      import (
      	"fmt"
      )
      
      func main() {
      	
      	type myInt int
      	var n1 myInt
      	var n2 int
          // n1 和n2  是不同的類型
      
      	n1=100
      	//n2=n1  // 報錯的, 不同的類型,除非強制轉換
      	n2=int(n1)
      	fmt.Println("n1=",n1,"n2=",n2);
      
      }
      
      

      demo2

      package main
      import (
      	"fmt"
      )
      
      type my func(int,int)int
      
      func main() {
        c:=SS(sum,100,200)
        fmt.Println(c);
      }
      
      func SS(dd my, a int,b int) int{
      	return dd(a,b)
      }
      
      func sum(a int,b int ) int {
      	return a+b
      }
      
      

      demo3

      package main
      import (
      	"fmt"
      )
      
      func main() {
        s,ss:=count(2,3)
        fmt.Println("sum=",s,"ss=",ss);
      }
      
      func count(a int,b int)(sum int,ss int){
      	sum=a+b
      	ss=a*b
      	return
      }
      
      
      

      可變參數

      package main
      import (
      	"fmt"
      )
      
      func main() {
      	n:=sum(3,4,10)
      
      	fmt.Println("sum=",n);
      }
      
      func sum(n1 int,args... int)int{
      
      	sum:=n1
      	for i := 0; i < len(args); i++ {
      		sum+=args[i]
      	}
      	return sum
      }
      

      init 函數

      介紹

      1. 每個源文件中都可以包含一個init函數,該函數會在main之前執行,被go的框架調用
      2. 通??梢栽谒锩孀鰅初始化操作

      注意

      1. 如果一個文件同時 包含全局變量,init 函數,main 函數,則執行流程是,全局變量->init->main
      package main
      import (
      	"fmt"
      )
      
      var a =test()
      func main() {
      	fmt.Println("main")
      }
      func init (){
      	fmt.Println("init")
      }
      func test()int{
      	fmt.Println("test")
      	return 100
      }
      

      結果為
      test
      init
      main
      2. init 函數主要的作用,完成一些初始化工作

      匿名函數

      一般只使用一次的函數

      package main
      import (
      	"fmt"
      )
      
      func main() {
      	a:=func(n1 int,n2 int)int{
      		return n1+n2
      	}(10,20)
      	fmt.Println(a);
      }
      

      全局變量

      package main
      import (
      	"fmt"
      )
      
      var (
      	F1=func(n1 int ,n2 int) int{
      		return n1*n2
      	}
      )
      
      func main() {
      	a:=func(n1 int,n2 int)int{
      		return n1+n2
      	}(10,20)
      	fmt.Println(a);
      
      	fmt.Printf("全局匿名函數 %d",F1(3,4))
      }
      
      

      閉包

      閉包就是一個函數和其他相關的引用環境組合的一個整體

      package main
      import (
      	"fmt"
      )
      
      func main() {
      	f:=AddUpper()
      	fmt.Println(f(1))  //1
      	fmt.Println(f(2))  //13
      }
      func AddUpper() func(int)int{
      	var n int =10
      	return func(x int)int{
      		n=n+x
      		return n
      	}
      }
      
      

      返回 11 13

      上面的代碼拆分就是

      package main
      import (
      	"fmt"
      )
      func main() {
      	var n int=10;
      	f:=func(x int)int{  //f:=AddUpper()
      		n=n+x
      		return n
      	}
      	fmt.Println(f(1))  //11
      	fmt.Println(f(2))  //13
      }
      

      案例
      根據傳入的文件名稱,如果沒后綴就加上,有就返回

      package main
      import (
      	"fmt"
      	"strings"
      )
      func main() {
      	f:=makeSuffix(".md")
      	fmt.Println("文件是",f("123"))
      	fmt.Println("文件是",f("123.md"))
      }
      
      func makeSuffix(suffix string )func (string) string{
      	//suffix  外部傳入的 和在這里生命一個差不多
      	return func(name string) string{
      		//if name 沒有后綴就加上,否則就直接返回
      		if !strings.HasSuffix(name,suffix) {
      			return name+suffix
      		}
      		return name
      	}
      }
      
      

      說白了,閉包就是可以保存上一次的引用

      defer 函數

      在函數中,我們經常需要創建資源 比如(數據庫連接,文件句柄,鎖等)為了在函數執行完畢后,能及時釋放資源,go的設計者 提出了defer (延時機制)

      package main
      import (
      	"fmt"
      )
      func main() {
      	res := sum(20,10)
      	fmt.Println("res=",res)  //4  32
      }
      
      func sum(n1 int,n2 int)int{
      	// 當執行defer的時候,暫時不執行,會將defer后面的語句進行壓棧,當函數執行完畢后,在從derfer按先入后出的方式出棧執行	
      	// 在defer 將語句放入到棧時,也會將相關的值拷貝同時進入棧,
      	// 資源釋放一般都會這弄
      	defer fmt.Println("ok1",n1) //3
      	defer fmt.Println("ok2",n2)//2
      	n1++  //21
      	n2++  //11
      
      	res:=n1+n2  // 32
      	fmt.Println("ok3 res=",res)// 1,32
      	return res
      }
      
      

      結果
      ok3 res= 32
      ok2 10
      ok1 20
      res= 32

      函數遞歸

      實例代碼

      package main
      import (
      	"fmt"
      )
      
      func main() {
      	//A(4)  // 遞歸方式,
      	A4(4);  // 模仿遞歸調用的流程
      }
      
      func A(a int ){
      	if(a>2){
      		a--
      		A(a)
      	}
      	fmt.Println("a=",a);
      }
      
      func A4(a int){
      	if(a>2){
      		a--
      		A3(a)
      	}
      	fmt.Println("a3=",a);
      
      }
      
      func A3(a int){
      	if(a>2){
      		a--
      		A2(a)
      	}
      	fmt.Println("a2=",a);
      
      }
      
      func A2(a int){
      	//a=2
      	if(a>2){
      		a--
      		A3(a)
      	}
      	fmt.Println("a1=",a);
      
      }
      
      
      

      遞歸調用其實表面就是自己調用自己,自己是沒法調用自己的,就像自己刪除自己沒法實現的。程序是這樣實現的。自己調用自己的時候,其實就是將自己拷貝了一份,然后再調用如代碼

      1. 先傳入4,條件滿足,-- 變成了3 又去調用自己(復制自己),此時等待3的結果
      2. 進入到3,條件滿足 -- 變成了2 又去調用自己(復制自己),此時等待2的結果
      3. 進入到2,條件不滿足 --直接打印 出2 返回給2等待地方
      4. 3接收到了2的結果后執行完if 又執行了打印,2
      5. 2接受3的結果 執行if 打印 3
      6. main 接受了4的結果

      內置函數

      1. len 用來求長度 stirng array slice map channel

      2. new 用來分配內存,主要用來分配值類型,int float32 返回的指針
        使用方式 n :=new(int) 值是0

      3. make 用來分配內存,主要用來分配引用類型,chan map slice

      時間

      常用格式

      package main
      import (
      	"fmt"
      	"time"
      )
      func main() {
      	now := time.Now() //獲取當前時間
      	fmt.Printf("時間:%v\n", now)
      	year := now.Year()     //年
          month := now.Month()   //月
          day := now.Day()       //日
          hour := now.Hour()     //小時
          minute := now.Minute() //分鐘
          second := now.Second() //秒
      	fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
      
      	timestamp1 := now.Unix()     //時間戳
          timestamp2 := now.UnixNano() //納秒時間戳
          fmt.Printf("現在的時間戳:%v\n", timestamp1)
          fmt.Printf("現在的納秒時間戳:%v\n", timestamp2)
      
      
      	timeObj := time.Unix(timestamp1, 0) //將時間戳轉為時間格式   2023-04-11 19:45:17 +0800 CST
      
      	fmt.Printf("時間戳轉換:%v\n", timeObj)
      
      	fmt.Printf("星期:%v\n", now.Weekday().String())
      	fmt.Printf("格式指定格式 %v \n",now.Format("2006-01-02 15:04:05"))
      
      }
      
      

      常用操作

      package main
      import (
      	"fmt"
      	"time"
      )
      func main() {
      	now := time.Now() //獲取當前時間
      	later := now.Add(time.Hour) // 當前時間加1小時后的時間
      	fmt.Println("當前時間增加一小時",later.Format("2006-01-02 15:04:05"))
      	fmt.Println("時間差",later.Sub(now))
      
      	//Equal 函數會考慮時區的影響,因此不同時區標準的時間也可以正確比較,Equal 方法和用 t==u 不同,Equal 方法還會比較地點和時區信息。
      	fmt.Println("當前時間比較:",now.Equal(now))
      	fmt.Println("下一個小時時間比較:",now.Equal(later))
      	//判斷一個時間點是否在另一個時間點之后:
      	fmt.Println("當前時間大于某時間",now.After(now.Add(-time.Hour)))
      	//判斷一個時間點是否在另一個時間點之前:
      	fmt.Println("當前時間小于某時間",now.Before(now.Add(time.Hour)))
      }
      
      

      定時器

      package main
      import (
      	"fmt"
      	"time"
      )
      func main() {
      	ticker := time.Tick(time.Second) //定義一個1秒間隔的定時器
          for i := range ticker {
              fmt.Println(i) //每秒都會執行的任務
          }
      
      }
      

      轉換

      package main
      import (
      	"fmt"
      	"time"
      )
      func main() {
      	var layout string = "2006-01-02 15:04:05"
          var timeStr string = "2023-04-11 15:22:12"
          timeObj1, _ := time.Parse(layout, timeStr)
          fmt.Println(timeObj1)
          timeObj2, _ := time.ParseInLocation(layout, timeStr, time.Local)
          fmt.Println(timeObj2)
      
      }
      

      go的每一個文件都是一個包,其實就和命名空間一樣
      用import "包路徑"
      如果提示找不到包 可以關閉mod go env -w GO111MODULE=off

      包結構

      package main
      import (
      	"fmt"
      	 "goCode/utils"	//這里直接是文件夾
      	 //u "goCode/utils"  //u 是取的別名
      )
      
      func main() {
      
      	fmt.Println("333")
      	result:=utils.Cal(2.3,2.7,'+')  // 這里是 包名.函數
      	fmt.Println("result=",result)
      }
      
      
      
      package utils
      import (
      	"fmt"
      	
      )
      
      //首寫比較是大寫 才能被外部使用
      func Cal(n1 float64,n2 float64,o byte ) float64{
      	switch o {
      		case '+':
      			return n1+n2
      		case '-':
      			return n1-n2
      		case '*':
      			return n1*n2
      		case '/':
      			return n1/n2
      		default:
      			fmt.Println("不支持的計算")
      		return -99999
      	}
      } 
      
      

      編譯項目

      1. 編譯只需要要編譯main所在目錄
      2. go build -o bin\ gocode.....\main 執行后會生成 exe文件 會放到bin里面
      3. pkg 庫文件

      異常處理

      默認情況下,程序報錯后會直接退出,

      我們希望程序報錯后,可以捕獲異常,并進行處理,保證程序可以正常執行

      go語言處理方式有 defer panic recover

      defer 在panic之前執行

      panic

      這玩意執行了,是不能恢復的。直接終止了

      defer+recover處理

      defer 是函數執行完后執行的, 如果有多個,他會從后往前執行。也就是會先執行最后一個

      package main
      import (
      	"fmt"
      )
      
      func test(){
      	defer func(){
      		err:=recover()  // reconver 系統內置函數,可以捕獲異常
      		if err!=nil{
      			// 拋出異常
      			fmt.Println("err=",err)
      		}
      	}()
      	n1:=10
      	n2:=0
      	n:=n1/n2 // 這里會報錯
      	fmt.Println("n=",n)
      }
      
      func main() {
      	test()
      
      	fmt.Println("執行完畢!")
      }
      
      
      

      自定義錯誤

      package main
      import (
      	"fmt"
      	"errors"
      )
      
      func test(n int)(err error){
      	if n==1{
      		return nil
      	}else{
      		//返回自定義錯誤
      		return errors.New("發生了錯誤")
      	}
      }
      
      func test1(){
      	err:=test(2)
      	if err!=nil{
      		//如果發生錯誤,就輸出這個錯誤,并且終止程序
      		panic(err)  
      	}
      	fmt.Println("發生錯誤后這里是不執行的")
      }
      
      func main() {
      	test1()
      
      	fmt.Println("執行完畢!")
      }
      

      命令行參數

      Variables

      • os.Agrs提供了簡單的命令行參數,以命令行參數個數作為標識,參數列表是一個切片,索引0代表程序本身,1代表第一個參數,以此類推,沒有更細粒度的參數區分,使用起來簡單
      • flag提供了更為科學的命令行參數處理辦法,提供更細粒度的和更全的參數解析,推薦使用

      os.Agrs

      os.Args 提供原始命令行參數訪問功能。注意,切片中的第一個參數是該程序的路徑,并且 os.Args[1:]保存所有程序的的參數。

      package main
      import (
      	"fmt"
      	"os"
      )
      
      func main() {
      	fmt.Println("命令行參數",len(os.Args))
      	for i,v:=range os.Args{
      		fmt.Printf("args[%v]=%v\n",i,v)
      	}
      
      }
      
      

      先執行go build main.go 生成exe程序

      cmd 進入 main.exe 參數1 參數2 慘數3

      flag包

      Args 的方式 傳參數 必須遵守 順序,解決這問題可以用flag 包 來解析命令行 參數可以隨意

      package main
      import (
      	"fmt"
      	"flag"
      )
      
      func main() {
      
      	var user string
      	var pwd string
      	var host string
      	var port int
      
      	// &user 就是接用戶命令行輸入的-u 
      	// u    就是-u指定參數
      	// ""  默認為空
      	//  說明
      	flag.StringVar(&user,"u","","用戶名,默認為空")
      	flag.StringVar(&pwd,"p","","密碼,默認為空")
      	flag.StringVar(&host,"h","","host,默認為空")
      	flag.IntVar(&port,"t",3306,"端口,默認為空")  // intvar
      
      	// 轉換
      	flag.Parse()
      	//main.exe -u root -p 123456 -h 192.168.2.3
      	fmt.Printf("user=%v,pwd=%v,host=%v,port=%v",user,pwd,host,port)
      
      }
      
      
      
      posted @ 2023-09-22 14:27  Jet-jing  閱讀(27)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 无码人妻精品一区二区三区下载 | 成全高清在线播放电视剧| 丝袜高潮流白浆潮喷在线播放| 4399理论片午午伦夜理片| 亚洲美免无码中文字幕在线| 国产一区二区三区精美视频| www久久只有这里有精品| 国产精品久久无码不卡黑寡妇| 中文熟妇人妻av在线| 久久久久青草线蕉亚洲| 久久大香伊蕉在人线免费AV| 色欲精品国产一区二区三区av| 国产亚洲欧洲av综合一区二区三区 | 国产360激情盗摄全集| 国产精品乱码一区二区三| 久久久欧美国产精品人妻噜噜| 佳木斯市| 久热久热久热久热久热久热| 亚洲国产精品综合久久20| 无遮挡aaaaa大片免费看| 中文字幕乱码中文乱码毛片| 国产精品国产三级国产试看| 成人免费ā片在线观看| 肥臀浪妇太爽了快点再快点| 国产精品午夜无码AV天美传媒| 99国精品午夜福利视频不卡99 | 亚洲成人av一区二区| 岛国岛国免费v片在线观看| 日日猛噜噜狠狠扒开双腿小说| 精品人妻系列无码天堂| 日韩中文字幕在线不卡一区| 久久被窝亚洲精品爽爽爽| 国产精品成人午夜福利| 午夜福利日本一区二区无码| 九九日本黄色精品视频| 四虎永久播放地址免费| √新版天堂资源在线资源| 国色天香成人一区二区| 无码人妻精品一区二区三区免费| 一区二区三区岛国av毛片| 噜噜噜噜私人影院|