go語言基礎循環語句、數組、切片


一、包管理

  就是模塊的意思,package main 代表的就是main包

  1.自定義包(例如在路徑下建立day2.1文件夾,里面包含s1.go,s2.go。然后在文件夾外面建立test.go文件夾)

-go語言的代碼必須放在gopath的src路徑下

-包導入是從gopath的src路徑下開始檢索(開始找)

-除了main包以外,建議包名就叫文件夾名,一個文件夾下的包名必須一致

-同一個包下,變量,函數只能定義一次

-同一個包下的變量和函數可以直接使用

-包內的函數或變量,想讓外部包使用,必須首字母大寫

-以后下的第三方包都是放在gopath的src路徑下

    在day2.1里面的s1,s2(若包里面的變量要給外部使用,變量名需要首字母大寫)

//day2.1里面的s1
package day2_1

import "fmt"


func Test()  {
    fmt.Println("我是day2下面的s1函數")
    fmt.Println(Name)
}



//day2.1里面的s2
package day2_1

import "fmt"

var Name = "aaa"

func test1()  {
    fmt.Println("我是day2下面的s2函數")
    fmt.Println(Name)
}

    在day2.1外面的test.go(此時調用day2.1里面的s1里面的函數Test)

package main

import (
    "fmt"
    "go/day2/day2.1"
)

func main()  {
    fmt.Println("我是根路徑下的函數")
    day2_1.Test()
    fmt.Println(day2_1.Name)
}

  

  2、init函數(-不需要調用就會執行,例如下面只要執行函數就會觸發,就會執行init函數。init函數可以定義多個

package day2_1

import "fmt"

//init特殊函數,初始化函數,在導包的時候就會執行,並且可以定義多個,可以用它來初始化包內的一些東西(比如下面初始化Name)
func init()  {
    Name = "bbb"
    fmt.Println("我是init函數")
}



func Test()  {
    fmt.Println("我是day2下面的s1函數")
    fmt.Println(Name)
}

 

  3、包的導入

方式一:直接導入
     -import "day02/mypackage"

方式二:-給包重命名(導入后就直接用名字.變量/函數在代碼中使用) -import 名字 "day02/mypackage"
方式三:
-包只導入,不使用(例如執行某個包里面的init函數,而不執行其他函數,此時導入就會執行init函數,而其他函數不執行) -import _ "day02/mypackage"

 

  4、采用go mod 模式

-兩種創建方式
1.
-命令行下輸入:go mod init 項目名(也可以自己在任何路徑下創建一個文件夾名),輸入命令后在當前路徑下創建出go.mod(該項目依賴go的版本,第三方包版本)
-項目路徑的cmd窗口,go get 第三方包,就會在go.mod中加入依賴
-以后把項目copy給別人,別人執行:go get
-自己寫的包,就放在自己項目路徑下
-加代理的方式:手動寫,goland中配置

2.
-在goland中創建項目時,直接指定modules,可以配置環境變量(加代理)

 

  5、if-else語句

package main

import "fmt"

//一定不要回車換行
func main()  {
    a := test()
    if a > 10{
        fmt.Println("a大於10")
    }else if a == 10{
        fmt.Println("a等於10")
    }else {
        fmt.Println("a小於10")
    }
}

func test() int {
    return 100
}

 

  6、循環

    沒有while循環,沒有do while循環,只有一個for循環

package main

/*
for循環
語法:
for 變量初始化條件;條件;變量自增/自減{
    循環內容
}
 */
func main()  {
    //基本使用
    //for i:=0;i<10;i++{
    //    fmt.Println(i)
    //}

    //省略初始化變量條件,放置到循環外
    //i:=0             //作用域范圍大,不止在for內部,外部也可以用
    //for ;i<10;i++{
    //    fmt.Println(i)
    //}

    //省略第三部分,放置到循環外
    //i:=0           //作用域范圍大,不止在for內部,外部也可以用
    //for ;i<10;{
    //    fmt.Println(i)
    //    i++
    //}

    //省略一和三部分的簡略寫法(這就是while循環)  for 條件{ 循環體內容}
    //i:=0
    //for i<10{
    //    fmt.Println(i)
    //    i++
    //}

    //死循環
    //for {
    //    fmt.Println("ssssss")
    //}

    //只是演示開多協程
    //for i:=0;i<4000;i++{
    //    go test2()
    //}

    //break :結束本次for循環,continue結束本次循環繼續下一次循環
}
//func test2()  {
//    for  {
//        fmt.Println("sssss")
//    }
//
//}

 

  7、Switch

    switch 是一個條件語句,用於將表達式的值與可能匹配的選項列表進行比較,並根據匹配情況執行相應的代碼塊。它可以被認為是替代多個 if else 子句的常用方式

package main
func main() {
    //1 基本使用
    //num:=4
    //switch num {
    //case 1:
    //    fmt.Println("1")
    //case 2:
    //    fmt.Println("2")
    //case 3:
    //    fmt.Println("3")
    //case 4:
    //    fmt.Println("4")
    //}

    //2 默認情況
    //num:=40
    //switch num {
    //case 1:
    //    fmt.Println("1")
    //case 2:
    //    fmt.Println("2")
    //case 3:
    //    fmt.Println("3")
    //case 4:
    //    fmt.Println("4")
    //default:
    //    fmt.Println("我沒有匹配")
    //}

    //3 多表達式判斷
    //num:=40
    //switch num {
    //case 1,2,3,4,5,6,7,8:
    //    fmt.Println("1")
    //case 10,11,16:
    //    fmt.Println("2")
    //case 30:
    //    fmt.Println("3")
    //case 40,44,45:
    //    fmt.Println("4")
    //default:
    //    fmt.Println("我沒有匹配")
    //}

    //4 無表達式的 switch
    //num:=80
    //switch  {
    //case num==12,num==13:
    //    fmt.Println("12,13")
    //case num==40,num==41:
    //    fmt.Println("40,41")
    //default:
    //    fmt.Println("我沒有匹配")
    //}
    
    //5 Fallthrough(此時相當於全部執行下面代碼。即全部打印)
    //num:=12
    //switch  {
    //case num==12,num==13:
    //    fmt.Println("12,13")
    //    fallthrough
    //case num==40,num==41:
    //    fmt.Println("40,41")
    //    //fallthrough                       //穿透,只要看到fallthrough,無條件執行下一個case或者default
    //default:
    //    fmt.Println("我沒有匹配")
    //}
}

  

  8、數組(基礎數組、數值長度、循環數組、多維數組相關)

    數組是同一類型元素的集合。可以放多個值,但是類型一致,內存中連續存儲。Go 語言中不允許混合不同類型的元素

package main

import (
    "fmt"
)

func main() {

    //1 數組的定義,數組的大小,在定義階段就確定了,而且不能改
    //定義了一個大小為3的string類型數組,里面可以放3個字符串
    //var names [3]string
    //var ages [3]int8
    //fmt.Println(ages)

    //2 數組賦值
    //var ages [3]int8
    //ages[0]=99           給第一個索引位設置為99
    //ages[2]=88
    //fmt.Println(ages)
    //fmt.Println(ages[1])

    //3 定義並初始化,
    //var ages [3]int=[3]int{1,2,3}
    //var ages [3]int=[3]int{1,2}
    //var ages [3]int=[3]int{}
    //var ages=[3]int{}
    //ages:=[3]int{1,3,4,7}  //不允許多放,此時報錯
    //fmt.Println(ages)

    //4 數組定義並初始化的其他。數組只要定義,長度就固定了,...后面放幾個值,數組大小就是多少
    //var ages [9]int=[...]int{1,2,3,4,5,6,7,8}   //不支持這個
    //var ages =[...]int{1,2,3,4,5,6,7,8}
    //ages :=[...]int{1,2,3,4,8}
    //fmt.Println(len(ages))

    //5 數組的大小是類型的一部分
    //var a [2]int=[2]int{1,2}
    //var b [3]int=[2]int{1,3}
    //var b1 [2]int=[2]int{1,3}
    //b=a   //此時a,b為兩個類型如果不是同一種類型,不允許相互賦值,而a,b1可以賦值
    //fmt.Println(b)

    //6 數組是值類型
    //var a [2]int=[2]int{1,2}
    //fmt.Println(a)       //[1 2]
    //test5(a)  //因為數組是值類型,go函數傳參,都是copy傳遞,如果是值類型,函數內改了,不會影響原來的   [99 2]
    //fmt.Println(a)     [1 2]

    //7 數組長度  len()  數組長度在定義階段已經固定
    //var a [2]int=[2]int{1,2}
    //fmt.Println(len(a))

    //8 數組循環
    //var a =[...]int{7,4,3,5,6,7}
    //fmt.Println(a[99])    會報錯
    //fmt.Println(len(a))
    //普通循環
    //for i:=0;i<len(a);i++{
    //    fmt.Println(a[i])
    //}

    //通過range來循環  (range不是內置函數,是一個關鍵字,for,if,else),打印出索引
    //for i:=range a{
    //    fmt.Println(i)
    //}

    //如果用一個變量來接收,這個值是可迭代的索引
    //如果用兩個變量來接收,這兩個變量,一個是索引,一個具體的值
    //for i,value:=range a{
    //    fmt.Println(i)
    //    fmt.Println(value)
    //}

    //把數組循環打印出來,此時就是不要索引
    //for _,value:=range a{
    //    fmt.Println(value)
    //}

    // 9 多維數組
    //var a [3][3]int  //定義:表示數組里面再放數組  [[0 0 0] [0 0 0] [0 0 0]]
    //a[0][1]=99      //使用   [[0 99 0] [0 0 0] [0 0 0]]
    //fmt.Println(a)

    //定義並賦初值
    //var a [3][3]int=[3][3]int{{1},{1,2,3},{4,4,4}}           //[[1 0 0] [1 2 3] [4 4 4]]
    //var s =[3][3]string{{"aaa","xxx","yyy"},{},{}}        //[[aaa xxx yyy] [  ] [  ]]
    //fmt.Println(s)
    //fmt.Println(a)
    
    //循環多維數組
    //for _,value:=range s{
    //    for _,in_value:=range value{
    //        fmt.Println(in_value)
    //    }
    //}

    //10 數組定義並指定位置初始化
    //var names [100]int=[100]int{10:99,99:99}     //代表給第十個位置賦值99,且第99個位置也賦值99
    //var names [100]int=[100]int{10,11,2,44,99:99,45:88}   //表示0,1,2,3索引位置為10,11,2,44.索引99位置賦值99,索引45位置賦值88
    //fmt.Println(names)
    
}

func test5(a [2]int)  {
    a[0]=99
    fmt.Println(a)

}

 

  9、切片基礎

    本質:切片是由數組建立的一種方便、靈活且功能強大的包裝(Wrapper)。切片本身不擁有任何數據。它們只是對現有數組的引用

package main

func main() {
    //1 切片定義的第一種方式
    //定義一個數組
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    //基於數組,做一個切片
    //[]int 中括號中不帶東西,就是切片類型
    //var b []int    此時也是定義切片
    //b:=a[:]
    //fmt.Println(b)                     //[9 8 7 6 5 4 3 2 1 0]
    //fmt.Printf("%T",b)         //[]int    []里面沒有東西代表為切片類型
    //fmt.Println()
    //fmt.Printf("%T",a)         //[10]int     數組類型
    //fmt.Println()

    ////2 使用切片,取索引位值
    //fmt.Println(b[0])
    //fmt.Println(b[1])

    ////3 修改切片,會影響數組
    //b[0]=999
    //fmt.Println(b)
    ////數組會被修改
    //fmt.Println(a)

    ////4 修改數組,也會影響切片。
    //a[3]=333
    //fmt.Println(a)  //數組
    //fmt.Println(b) //切片

    // 5 切片只切數組一部分
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    //var b []int=a[3:5]       //此時[6 5]
    //fmt.Println(b)
    ////修改切片
    //b[0]=999
    //fmt.Println(b)
    //fmt.Println(a)         //雖然是改的b,但是也會影響a,此時a也會影響和b變化一樣。 數組切片互相影響
    //a[4]=888
    //fmt.Println(b)
    //fmt.Println(a)

    //6 當多個切片共用相同的底層數組時,每個切片所做的更改將反映在數組中。abc都會相互影響
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    //var b []int=a[3:5]
    //var c []int=a[4:6]
    //fmt.Println(a)
    //fmt.Println(b)
    //fmt.Println(c)
    //b[1]=555
    //fmt.Println(a)
    //fmt.Println(b)
    //fmt.Println(c)

    ////7 切片的長度和容量
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    ////var b []int=a[3:4]
    //fmt.Println(a)
    //fmt.Println(b)
    //// 切片長度
    //fmt.Println(len(b))        此時切多少長度就是多少,此時為1
    //// 切片容量(我最多能存多少值)
    //fmt.Println(cap(b))     此時b的容量為7,因為是從3開始且,此時指針在索引位置3,對應a中的數值6,指針后面還有7位。所以容量為切片初始位置到原數組結束位置

    ////8 切片追加值
    //b=append(b,5)          [6,5]  會在索引3對應的值6后面加5
    //b=append(b,999)      
    ////到了臨界點可再追加,但是臨界點后的數據不能加進原數組,臨界點前的數據可以影響原數組。
    //b=append(b,888)
    //fmt.Println(b)
    //fmt.Println(a)
    //
    //fmt.Println(len(b))// 長度是4
    //fmt.Println(cap(b))  //容量是6
    //b[0]=111
    //fmt.Println(b)
    //fmt.Println(a)

    //注意只要超出臨界點追加,此時b就會新建一個數組,自動擴容,且容量為原來的兩倍,此時對b修改,那么不會影響a數組

}

     切片之append()和copy()函數

      如果想增加切片的容量,我們必須創建一個新的更大的切片並把原分片的內容都拷貝過來。

package main

import "fmt"

func main() {
    var numbers []int                //定義空切片
    printSlice(numbers)             //len=0 cap=0 slice=[]

    //允許追加空切片
    numbers = append(numbers, 0)
    fmt.Println(numbers)                 //[0]
    printSlice(numbers)                 //len=1 cap=1 slice=[0] 追加空切片后

    //向切片添加一個元素
    numbers = append(numbers, 1)
    fmt.Println(numbers)               //[0 1]
    printSlice(numbers)                //len=2 cap=2 slice=[0 1]

    // 同時添加多個元素
    numbers = append(numbers, 2,3,4)
    fmt.Println(numbers)               //[0 1 2 3 4]
    printSlice(numbers)                //len=5 cap=6 slice=[0 1 2 3 4]

    //創建切片 numbers1 是之前切片的兩倍容量,創建切片用make
    numbers1 := make([]int, len(numbers), (cap(numbers))*2)
    fmt.Println(numbers1)             //[0 0 0 0 0] 
    printSlice(numbers1)             //len=5 cap=12 slice=[0 0 0 0 0]

    //拷貝 numbers 的內容到 numbers1 
    copy(numbers1,numbers)
    printSlice(numbers1)           //len=5 cap=12 slice=[0 1 2 3 4]
}

     

    切片之刪除元素

      Go語言並沒有對刪除切片元素提供專用的語法或者接口,需要使用切片本身的特性來刪除元素,根據要刪除元素的位置有三種情況,分別是從開頭位置刪除、從中間位置刪除和從尾部刪除,其中                           刪 除切片尾部的元素速度最快。

    1.從開頭位置開始刪除(直接移動數據指針)

a = []int{1, 2, 3}
a = a[1:] // 刪除開頭1個元素
a = a[N:] // 刪除開頭N個元素

      (不移動指針,不會導致內存空間結構的變化)

a = []int{1, 2, 3}
a = append(a[:0], a[1:]...) // 刪除開頭1個元素
a = append(a[:0], a[N:]...) // 刪除開頭N個元素

      (使用copy函數)

a = []int{1, 2, 3}
a = a[:copy(a, a[1:])] // 刪除開頭1個元素
a = a[:copy(a, a[N:])] // 刪除開頭N個元素

 

    2.從中間位置刪除

a = []int{1, 2, 3, ...}
a = append(a[:i], a[i+1:]...) // 刪除中間1個元素
a = append(a[:i], a[i+N:]...) // 刪除中間N個元素
a = a[:i+copy(a[i:], a[i+1:])] // 刪除中間1個元素
a = a[:i+copy(a[i:], a[i+N:])] // 刪除中間N個元素

    

    3、從尾部刪除

a = []int{1, 2, 3}
a = a[:len(a)-1] // 刪除尾部1個元素
a = a[:len(a)-N] // 刪除尾部N個元素

  例子:

package main
import "fmt"
func main() {
    seq := []string{"a", "b", "c", "d", "e"}
    // 指定刪除位置
    index := 2

    // 查看刪除位置之前的元素和之后的元素,index為索引位置
    fmt.Println(seq[:index], seq[index+1:]) //[a b] [d e]

    // 將刪除點前后的元素連接起來
    seq = append(seq[:index], seq[index+1:]...) 
    fmt.Println(seq)      //[a b d e]
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM