乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Go語言中復(fù)合的數(shù)據(jù)類型

       印度阿三17 2020-03-16

      數(shù)組

      數(shù)組是同一種數(shù)據(jù)類型元素的集合。在Go語言中,數(shù)組從聲明時就確定,可以對其成員進行修改,但是不可以修改數(shù)組的大小。

      數(shù)組的定義

      數(shù)組的基本定義語法如下:

      var 數(shù)組名 [數(shù)組大小]類型

      比如定義一個長度為3,類型是int的數(shù)組:

      var a [3]int

      注意:長度必須是常量,它是數(shù)組類型的一部分,一旦定義,長度不能改變。

      數(shù)組的初始化

      (1)、初始化數(shù)組時可以使用初始化列表來設(shè)置數(shù)組元素的值。

      func main() {
          var testArray [3]int                        //數(shù)組會初始化為int類型的零值
          var numArray = [3]int{1, 2}                 //使用指定的初始值完成初始化
          var cityArray = [3]string{"北京", "上海", "深圳"} //使用指定的初始值完成初始化
          fmt.Println(testArray)                      //[0 0 0]
          fmt.Println(numArray)                       //[1 2 0]
          fmt.Println(cityArray)                      //[北京 上海 深圳]
      }

      (2)、按照上面的方法每次都要確保提供的初始值和數(shù)組長度一致,一般情況下我們可以讓編譯器根據(jù)初始值的個數(shù)自行推斷數(shù)組的長度,例如:

      func main() {
          var testArray [3]int
          var numArray = [...]int{1, 2}
          var cityArray = [...]string{"北京", "上海", "深圳"}
          fmt.Println(testArray)                          //[0 0 0]
          fmt.Println(numArray)                           //[1 2]
          fmt.Printf("type of numArray:%T\n", numArray)   //type of numArray:[2]int
          fmt.Println(cityArray)                          //[北京 上海 深圳]
          fmt.Printf("type of cityArray:%T\n", cityArray) //type of cityArray:[3]string
      }

      (3)、我們還可以使用指定索引值的方式來初始化數(shù)組,例如:

      func main() {
          a := [...]int{1: 1, 3: 5}
          fmt.Println(a)                  // [0 1 0 5]
          fmt.Printf("type of a:%T\n", a) //type of a:[4]int
      }

      數(shù)組的遍歷

      數(shù)組的遍歷有兩種方法:

      • for range

      • 通過索引遍歷

      如下:

      package main
      
      import "fmt"
      
      func main() {
          var a = [...]string{"北京", "上海", "廣州"}
          // 通過索引遍歷數(shù)組
          for i := 0; i < len(a); i   {
              fmt.Println(a[i])
          }
          fmt.Println("================")
      
          // 用for range遍歷數(shù)組
          for _, v := range a {
              fmt.Println(v)
          }
      }

      多維數(shù)組

      Go語言支持多維數(shù)組,這里以二維數(shù)組為例。

      二維數(shù)組的定義

      二維數(shù)組的基本定義如下:

      var 數(shù)組名 [數(shù)組大小][數(shù)組大小]類型

      如下表示外層數(shù)組有三個元素,里層數(shù)組有兩個元素的二維數(shù)組:

      var a [3][2]int

      二維數(shù)組的初始化

      package main
      
      import "fmt"
      
      func main() {
          var cities = [3][2]string{
              {"北京", "上海"},
              {"廣州", "重慶"},
              {"四川", "貴州"},
          }
          fmt.Println(cities)
      }

      如果要用自動推導(dǎo)數(shù)組長度,只有第一層可以使用,如下:

      //支持的寫法
      a := [...][2]string{
          {"北京", "上海"},
          {"廣州", "深圳"},
          {"成都", "重慶"},
      }
      //不支持多維數(shù)組的內(nèi)層使用...
      b := [3][...]string{
          {"北京", "上海"},
          {"廣州", "深圳"},
          {"成都", "重慶"},
      }

      注意:數(shù)組是值類型的,其賦值和傳參會復(fù)制整個數(shù)組,因此改變副本的值,不會改變本身的值。如下:

      package main
      
      import "fmt"
      
      func main() {
          var cities = [3][2]string{
              {"北京", "上海"},
              {"廣州", "重慶"},
              {"四川", "貴州"},
          }
          // fmt.Println(cities)
          c2 := cities
          c2[2][0] = "黑龍江"
          fmt.Println(cities)
          fmt.Println(c2)
      }

      其輸出結(jié)果為:

      [[北京 上海] [廣州 重慶] [四川 貴州]]
      [[北京 上海] [廣州 重慶] [黑龍江 貴州]]

      3.3、切片

      數(shù)組的長度是不可變的,一旦我們定義了某個數(shù)組,其長度就固定了。而切片是對數(shù)組的一層封裝,它是擁有相同類型元素的可變長度序列。它非常靈活,支持自動擴容。

      切片是一個引用類型,其底層依然是某個數(shù)組,如果底層數(shù)據(jù)改變,切片也會相應(yīng)的改變。切片的內(nèi)容包括地址 長度 容量 。它一般用來快速的操作一塊數(shù)據(jù)集合。

      自定義切片

      切片的基本語法如下:

      var 變量名 []元素類型

      注意:在定義切片的時候,不指定其長度。

      例如:

      package main
      
      import "fmt"
      
      func main() {
          // 定義切片
          var s1 []int
          var s2 []string
          var s3 []bool
          fmt.Println(s1, s2, s3)
      }

      由于切片是引用類型,它不支持直接比較,只支持和nil 比較,如下:

      package main
      
      import "fmt"
      
      func main() {
          // 定義切片
          var s1 []int
          var s2 []string
          var s3 []bool
          fmt.Println(s1, s2, s3)
          fmt.Println(s1 == nil)
          fmt.Println(s2 == nil)
          fmt.Println(s3 == nil)
          // fmt.Println(s1 == s3) // 不能這么比較
      }

      自定義切片的初始化

      切片的初始化和數(shù)組一樣,因為其底層本身就是數(shù)組。比如:

      package main
      
      import "fmt"
      
      func main() {
          // 定義切片并初始化
          var s4 = []int{1, 2, 3, 4}
          var s5 = []string{"北京", "上海"}
          var s6 = []bool{true, false}
          fmt.Println(s4, s5, s6)
      }

      基于數(shù)組定義切片

      我們知道切片底層是存儲,所以切片也可以基于數(shù)組進行定義。如下:

      package main
      
      import "fmt"
      
      func main() {
          // 基于數(shù)組定義切片
          // 先定義一個數(shù)組
          var a1 = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
          // 然后對數(shù)組進行切割
          var a2 = a1[2:6]
          var a3 = a1[1:]
          var a4 = a1[:4]
          var a5 = a1[:]
          fmt.Println(a1, a2)
      }

      基于切片定義切片

      切片還可以基于切片定義切片。如下:

      package main
      
      import "fmt"
      
      func main() {
          // 基于切片定義切片
          // 定義一個切片
          var s = []int{1,2,3,4,5,6,7,8,9}
          // 對切片進行切割
          var s1 = s[2:4]
          fmt.Println(s1)
      }

      注意:對切片進行再切片的時候,其索引不能超過原數(shù)組的長度。

      切片的長度和容量

      切片擁有自己的長度和容量,我們可以通過使用內(nèi)置的len()函數(shù)求長度,使用內(nèi)置的cap()函數(shù)求切片的容量。

      package main
      
      import "fmt"
      
      func main() {
          // 基于切片定義切片
          // 定義一個切片
          var s = []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
          // 對切片進行切割
          var s1 = s[2:4]
          fmt.Println(s1)
          fmt.Printf("len(s1):%d  cap(s1):%d", len(s1), cap(s1))
      }

      輸出如下:

      [3 4]
      len(s1):2  cap(s1):7

      說明:

      • len函數(shù)求出來的長度就是切片的現(xiàn)有長度

      • cap函數(shù)求出來的容量是從切片起始位置到數(shù)組末尾的長度

      用make函數(shù)構(gòu)造切片

      上面介紹的都是通過數(shù)組來定義切片,不論是通過自定義還是從數(shù)組切片來的,其長度和容量都在定義的時候固定了。那么,如果我們需要動態(tài)創(chuàng)建一個切片,就需要使用make 函數(shù),格式如下:

      make([]T, size, cap)

      說明:

      • T:表示元素的類型

      • size:表示元素的數(shù)量

      • cap:表示切片的容量

      比如,我們創(chuàng)建一個元素個數(shù)是5,容量是10的切片。

      package main
      
      import "fmt"
      
      func main() {
          s := make([]int, 5, 10)
          fmt.Println(s)
          fmt.Printf("len(s):%d cap(s):%d\n", len(s), cap(s))
      }

      輸出如下:

      [0 0 0 0 0]
      len(s):5 cap(s):10

      如果我們不指定容量,其默認(rèn)和前面的元素個數(shù)一致,如下:

      package main
      
      import "fmt"
      
      func main() {
          s := make([]int, 5)
          fmt.Println(s)
          fmt.Printf("len(s):%d cap(s):%d", len(s), cap(s))
      }

      輸出如下:

      [0 0 0 0 0]
      len(s):5 cap(s):5

      切片的本質(zhì)

      切片的本質(zhì)就是對底層數(shù)組的封裝,它包含了三個信息:底層數(shù)組的指針、切片的長度(len)和切片的容量(cap)。

      舉個例子,現(xiàn)在有一個數(shù)組a := [8]int{0, 1, 2, 3, 4, 5, 6, 7},切片s1 := a[:5],相應(yīng)示意圖如下。

      88naCT.png

      切片s2 := a[3:6],相應(yīng)示意圖如下:

      88nd8U.png

      切片之間是不能比較的,我們不能使用==操作符來判斷兩個切片是否含有全部相等元素。 切片唯一合法的比較操作是和nil比較。 一個nil值的切片并沒有底層數(shù)組,一個nil值的切片的長度和容量都是0。但是我們不能說一個長度和容量都是0的切片一定是nil,例如下面的示例:

      var s1 []int         //len(s1)=0;cap(s1)=0;s1==nil
      s2 := []int{}        //len(s2)=0;cap(s2)=0;s2!=nil
      s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil

      所以要判斷一個切片是否是空的,要是用len(s) == 0來判斷,不應(yīng)該使用s == nil來判斷。

      注意以下三點:

      • 切片不保存具體的值

      • 切片對應(yīng)一個底層數(shù)組

      • 底層數(shù)組都是占用一塊連續(xù)的內(nèi)存空間

      切片的賦值拷貝

      我們知道切片的本質(zhì)是對底層數(shù)組的封裝,是一個引用類型,所以如果兩個切片共用底層數(shù)組,那么對一個切片進行修改會影響另一個切片的內(nèi)容,如下:

      package main
      
      import "fmt"
      
      func main() {
          s := make([]int, 5)
          fmt.Println(s)
          fmt.Printf("len(s):%d cap(s):%d\n", len(s), cap(s))
          s1 := s
          s1[0] = 100
          fmt.Println(s)
          fmt.Println(s1)
      }

      其輸出結(jié)果如下:

      [0 0 0 0 0]
      len(s):5 cap(s):5
      [100 0 0 0 0]
      [100 0 0 0 0]

      用copy函數(shù)復(fù)制切片

      上面介紹的賦值拷貝,兩個切片是共用同一個底層數(shù)組,對任意一個進行修改就會影響另一個切片。Go語言中有另一個函數(shù)copy(),它是會開辟另外一個內(nèi)存空間用來保存復(fù)制來的切片,通過這個函數(shù)復(fù)制的切片與原切片沒有任何關(guān)系。

      其基本語法如下:

      copy(destSlice, srcSlice)

      其中:

      • destSlice:是目標(biāo)切片

      • srcSlice:是源切片

      例如:

      package main
      
      import "fmt"
      
      func main() {
          // 定義一個切片并初始化
          s1 := []int{1, 2, 3, 4}
          // 再定義一個切片
          s2 := make([]int, 4, 4)
          // 用copy()函數(shù)進行復(fù)制
          copy(s2, s1)
          // 輸出:源切片s1:[1 2 3 4]  目標(biāo)切片s2:[1 2 3 4]
          fmt.Printf("源切片s1:%v  目標(biāo)切片s2:%v\n", s1, s2)
          // 對源切片進行修改,觀察目標(biāo)切片有無變化
          s1[0] = 100
          // 輸出:源切片s1:[100 2 3 4]  目標(biāo)切片s2:[1 2 3 4]
          fmt.Printf("源切片s1:%v  目標(biāo)切片s2:%v\n", s1, s2)
          // 對目標(biāo)切片進行修改,觀察源切片有無變化
          s2[1] = 300
          // 輸出:源切片s1:[100 2 3 4]  目標(biāo)切片s2:[1 300 3 4]
          fmt.Printf("源切片s1:%v  目標(biāo)切片s2:%v\n", s1, s2)
      }

      從上面可以看出,用copy 復(fù)制的切片,相互之前并不影響。

      切片的遍歷

      切片的遍歷和數(shù)組一樣,如下:

      package main
      
      import "fmt"
      
      func main() {
          s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
          // 第一種:遍歷索引
          for i := 0; i < len(s); i   {
              fmt.Println(s[i])
          }
          // 第二種:用for range遍歷
          for i, v := range s {
              fmt.Println(i, v)
          }
      }

      給切片添加元素

      上面介紹了切片的長度不是固定,那么我們就可以往切片里添加新的內(nèi)容。在Go語言中,給切片添加內(nèi)容是用append()方法。

      注意:

      1. 如果切片的容量夠用,則直接向切片中添加內(nèi)容;

      2. 如果切片的容量不夠,則會先一定的策略進行擴容,然后再向里面添加內(nèi)容;

      比如:

      package main
      
      import "fmt"
      
      func main() {
          // 定義一個數(shù)組
          a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
          // 然后從數(shù)組得到一個切片
          s := a[:4]
          // 然后打印切片的長度和容量,這時候的長度是小于容量的。
          // 輸出:[1 2 3 4] len(s):4 cap(s):9
          fmt.Printf("%v len(s):%d cap(s):%d\n", s, len(s), cap(s))
          // 我們對切片s進行添加元素操作
          s = append(s, 100)
          // 輸出:[1 2 3 4 100] len(s):5 cap(s):9
          fmt.Printf("%v len(s):%d cap(s):%d\n", s, len(s), cap(s))
      
          // 我們重新從數(shù)組得到一個切片,這次用全量的
          s2 := a[:]
          // 輸出:[1 2 3 4 100 6 7 8 9] len(s2):9 cap(s2):9
          fmt.Printf("%v len(s2):%d cap(s2):%d\n", s2, len(s2), cap(s2))
          // 我們對其進行添加元素
          s2 = append(s2, 200)
          // 輸出:[1 2 3 4 100 6 7 8 9 200] len(s2):10 cap(s2):18
          fmt.Printf("%v len(s2):%d cap(s2):%d\n", s2, len(s2), cap(s2))
      
      }

      上面的輸出正好驗證了我們所說,如果切片的容量充足,添加元素則直接再后面追加;如果切片容量不足,添加元素則先對容量進行擴充,再在后面添加元素。

      當(dāng)然,append() 函數(shù)還支持一次性擴容多個元素,如下:

      package main
      
      import "fmt"
      
      func main() {
          // 定義一個數(shù)組
          a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
          // 我們重新從數(shù)組得到一個切片,這次用全量的
          s2 := a[:]
          // 輸出:[1 2 3 4 100 6 7 8 9] len(s2):9 cap(s2):9
          fmt.Printf("%v len(s2):%d cap(s2):%d\n", s2, len(s2), cap(s2))
          // 我們對其進行添加元素
          s2 = append(s2, 200)
          // 輸出:[1 2 3 4 100 6 7 8 9 200] len(s2):10 cap(s2):18
          fmt.Printf("%v len(s2):%d cap(s2):%d\n", s2, len(s2), cap(s2))
          s2 = append(s2, 300, 400, 500)
          fmt.Printf("%v len(s2):%d cap(s2):%d\n", s2, len(s2), cap(s2))
      }

      切片的擴容策略

      通過上面對切片添加元素知道當(dāng)切片的容量不足的時候會先給切片擴容。擴容也是有一定策略的,其策略如下:

      1. 如果申請的容量大于原來容量的2倍,最終的容量則是申請的容量大?。?/p>

      2. 如果舊切片的容量小于1024,則最終容量是舊容量的2倍;

      3. 如果舊切片的容量大于1024,則最終容量是從舊容量開始循環(huán)增加原來的1/4,直到最終容量大于等于新申請的容量;

      4. 如果最終容量計算值溢出,則最終容量是新申請容量;

      注意:切片擴容還會根據(jù)切片中元素的類型不同而做不同的處理,比如intstring類型的處理方式就不一樣。

      從切片中刪除元素

      Go語言中并沒有刪除切片元素的專用方法,但是我們可以使用切片本身的特性來刪除元素。

      比如要刪除切片a中所以為index的元素,則用以下方法:

      a = append(a[:index], a[index 1:]...)

      例如:

      package main
      
      import "fmt"
      
      func main() {
          // 定義一個切片
          s1 := []int{1, 2, 3, 4, 5}
          // 從切片中刪除值為3的元素
          s1 = append(s1[:2], s1[3:]...)
          // 輸出:[1 2 4 5]
          fmt.Println(s1)
      }

      我們從切片中刪除某個元素對原數(shù)組有什么影響呢?我們看下面這個例子:

      package main
      
      import "fmt"
      
      func main() {
          // 定義一個數(shù)組
          a := [...]int{1, 2, 3, 4, 5, 6}
          s2 := a[:]
          s2 = append(s2[:2], s2[3:]...)
          fmt.Println(s2) // 輸出:[1 2 4 5 6]
          fmt.Println(a)  // 輸出:[1 2 4 5 6 6]
      }

      我們可以看到從切片中刪除某個元素,對原數(shù)據(jù)也有影響。如下圖:

      88uEzF.png

      來源:https://www./content-4-660551.html

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多