數(shù)組
在內(nèi)存中連續(xù)存儲的多個同一類型元素的集合灰殴,Go 語言中不允許混合不同類型的元素砍鸠,數(shù)組中的所有元素都被自動賦值為數(shù)組類型的零值涡拘,數(shù)組中的每個變量都可以使用數(shù)組下標訪問唉堪,len()函數(shù)返回數(shù)組元素個數(shù)
數(shù)組一般聲明語法如下:
var 數(shù)組變量名 [數(shù)組元素數(shù)量] 元素的數(shù)據(jù)類型
package main
import "fmt"
func main() {
var a [3] int//聲明一個長度為3的int數(shù)組
fmt.Println(a)//輸出[0 0 0]
}
簡略聲明也可以用來聲明數(shù)組分衫,不需要給數(shù)組中所有元素賦值场刑,而且還可以忽略數(shù)組長度,使用...代替蚪战,這種形式聲明的數(shù)組牵现,初始化索引的順序是無關(guān)緊要的,而且沒用到的索引可以省略邀桑,未指定初始值的元素將用零值初始化
package main
import "fmt"
func main() {
a := [3] int {1,2,3}//簡略聲明一個長度為3的int數(shù)組,并給每一個元素賦值
fmt.Println(a)//輸出[1 2 3]
b := [3] int {1}//簡略聲明一個長度為3的int數(shù)組,給第一個元素賦值為1瞎疼,剩下元素自動填充默認值0
fmt.Println(b)//輸出[1 0 0]
c := [...] int {1,2,3,4,5}//簡略聲明一個不確定長度的數(shù)組,后面跟了5個元素的賦值概漱,編譯器會自動計算數(shù)組長度為5
fmt.Println(c)//輸出[1 2 3 4 5]
d := [...] int {9:2}//簡略聲明一個數(shù)組丑慎,數(shù)組下標為9的元素為2,其余為int類型零值
fmt.Println(d)//輸出[0 0 0 0 0 0 0 0 0 2]
e := [3] int {}//簡略聲明一個長度為3的數(shù)組瓤摧,未賦值
fmt.Println(e)//輸出[0 0 0]
}
長度不同的數(shù)組在go語言中是不同類型的竿裂,長度不同的數(shù)組之間不能轉(zhuǎn)換
package main
import "fmt"
func main() {
a := [3] int {1}
b := [...] int {1,2,3}
a = b//a,b數(shù)組長度相同照弥,可以當做是同一類型
fmt.Println(a)//a數(shù)據(jù)的值改變腻异,輸出[1 2 3]
c := [...] int {1}
//b = c//b,c數(shù)組長度不同这揣,會報錯cannot use c (type [1]int) as type [3]int in assignment
fmt.Println(c)//輸出[1]
}
go中的數(shù)組是值類型不是引用類型悔常,數(shù)組賦值給新變量,新變量得到的是原數(shù)組的副本给赞,新變量中的數(shù)組改變不會影響原數(shù)組
package main
import "fmt"
func main() {
a := [...] int {1,2,3}
b := a
b[0] = 9//改變了數(shù)組b的第一個元素
fmt.Println(a)//原數(shù)組不會改變机打,輸出[1 2 3]
fmt.Println(b)//輸出[9 2 3]
}
多維數(shù)組
go語言也可以創(chuàng)建多維數(shù)組,多維數(shù)組很容易管理具有父子關(guān)系的數(shù)據(jù)或者與坐標系相關(guān)聯(lián)的數(shù)據(jù)
package main
import "fmt"
func main() {
a := [3][2] int {//創(chuàng)建一個二維數(shù)組
{1,2},
{3,4},
{5,6},//此處的,是必要的
}
fmt.Println(a[0][1])//輸出2
}
只要類型一致,就可以將多維數(shù)組互相賦值
package main
import "fmt"
func main() {
a := [2][2] int {{1,2},{1,2}}
b := [2][2] int {{3,2},{3,2}}
fmt.Printf("改變前a:%d\n",a)
fmt.Printf("改變前b:%d\n",b)
a = b
fmt.Printf("改變后a:%d\n",a)
fmt.Printf("改變后b:%d\n",b)
/*
輸出:
改變前a:[[1 2] [1 2]]
改變前b:[[3 2] [3 2]]
改變后a:[[3 2] [3 2]]
改變后b:[[3 2] [3 2]]
*/
}
也可以將多維數(shù)組中的某個維度當做一個數(shù)組片迅,或指定多維下標指定多維數(shù)組中某一值
package main
import "fmt"
func main() {
a := [2][2] int {{1,2},{3,4}}//二維數(shù)組中每個維度都是一個一維數(shù)組
var array [2]int = a[1]//取出二維數(shù)組a中下標為1的維度残邀,即[3,4]
var value int = a[1][0]//取出二維數(shù)組a中一維下標為1,二維下標為0的值柑蛇,即3
fmt.Println(array)
fmt.Println(value)
/*
輸出:
[3 4]
3
*/
}
數(shù)組冒泡排序
package main
import "fmt"
func main(){
arrary :=[...]int{3,9,8,6,4,0,1}
temp:=0
fmt.Printf("排序前%d",arrary)
for i:=0;i<len(arrary)-1;i++{
//控制相鄰元素比較芥挣,滿足條件交換數(shù)據(jù)
for j:=0;j<len(arrary)-i-1;j++{
if(arrary[j]>arrary[j+1]){
temp=arrary[j]
arrary[j]=arrary[j+1]
arrary[j+1]=temp
}
}
}
fmt.Printf("排序后%d",arrary)
}
切片
切片是由數(shù)組建立的一種方便、靈活且功能強大的包裝耻台,是對數(shù)組一個連續(xù)片段的引用空免。切片本身不擁有任何數(shù)據(jù)。它們只是對現(xiàn)有數(shù)組的引用,切片的長度是切片中的元素數(shù)盆耽。Go語言切片的內(nèi)部結(jié)構(gòu)包含地址蹋砚、大小和容量扼菠,切片的容量是從創(chuàng)建切片索引開始的底層數(shù)組中元素數(shù)
切片的聲明語法如下:
var 切片對象名 [] 數(shù)據(jù)類型 = 目標切片對象 [開始位置:結(jié)束位置]
例如:
package main
import "fmt"
func main() {
a := [5] int {1,2,3,4,5}
var b [] int = a[1:4]//創(chuàng)建一個a數(shù)組下標從1到(4-1)的切片
fmt.Printf("a:%d \n",a)//輸出a:[1 2 3 4 5]
fmt.Printf("b:%d \n",b)//b:[2 3 4]
//簡略寫法聲明數(shù)組
aa := [] int {1,2,3}//創(chuàng)建一個長度為3的數(shù)組,并返回其的切片引用都弹,所以a是切片
fmt.Printf("aa:%d \n",aa)//輸出a:[1 2 3]
}
切片默認指向一段連續(xù)內(nèi)存區(qū)域娇豫,可以是數(shù)組,也可以是切片本身畅厢,聲明切片的格式中冯痢,開始和結(jié)束范圍都被忽略,生成的切片將表示和原切片或數(shù)組一致的切片框杜,并且生成的切片與原切片或數(shù)組在數(shù)據(jù)內(nèi)容上是一致的;把切片的開始和結(jié)束位置都設(shè)為 0 時浦楣,生成的切片將變空
package main
import "fmt"
func main() {
a := [5] int {1,2,3,4,5}
var b [] int = a[0:3]//數(shù)組生成切片
var c [] int = b[0:2]//切片生成切片
fmt.Println(a,b,c)//輸出[1 2 3 4 5] [1 2 3] [1 2]
var bb [] int = a[:]//數(shù)組生成切片
var cc [] int = bb[:]//切片生成切片
fmt.Println(a,bb,cc)//輸出[1 2 3 4 5] [1 2 3 4 5] [1 2 3 4 5]
fmt.Println(cc[0:0])//空切片,輸出[]
}
切片自己不擁有任何數(shù)據(jù),只是底層數(shù)組的一種表示,對切片所做的任何修改都會反映在底層數(shù)組中
package main
import "fmt"
func main() {
a := [5] int {1,2,3,4,5}
b := a[2:3]//數(shù)組a從下標2到下標3-1的切片咪辱,即元素3
fmt.Printf("修改切片前:%d\n",a)
b[0] = b[0] + 1
fmt.Printf("修改切片后:%d\n",a)
/*
輸出:
修改切片前:[1 2 3 4 5]
修改切片后:[1 2 4 4 5]
*/
}
使用make()函數(shù)可以動態(tài)生成切片振劳,語法格式如下
make([]數(shù)據(jù)類型,切片元素數(shù)量,預(yù)分配的元素數(shù)量)
package main
import "fmt"
func main() {
a := make([]int,2,3)//使用make()函數(shù)生成切片
fmt.Println(a,len(a),cap(a))//輸出[0 0] 2 3
}
使用 make() 函數(shù)生成的切片一定發(fā)生了內(nèi)存分配操作
使用append()函數(shù)可以為切片添加元素,使用append()函數(shù)添加切片元素油狂,如果切片容量不夠會重新分配內(nèi)存
package main
import "fmt"
func main() {
var a [] int
for i:= 1;i <= 10;i++{
a = append(a,i)//向切片a中添加元素
fmt.Printf("len:%d,cap:%d,%d\n",len(a),cap(a),a)
}
}
上面的方法是向切片尾部添加元素历恐,下面是向切片頭部添加元素,每一次都會導(dǎo)致重新分配內(nèi)存专筷,向切片的頭部添加元素的性能要比從尾部追加元素的性能差很多
package main
import "fmt"
func main() {
a := [] int {1}
fmt.Println(a)//輸出[1]
a = append([] int {3},a...)//向切片頭部添加元素
fmt.Println(a)//輸出[3 1]
}
使用copy()函數(shù)可以復(fù)制一個數(shù)組切片到另一個數(shù)組切片弱贼,若兩個數(shù)組切片不一樣大,會按較小的數(shù)組切片的元素個數(shù)進行復(fù)制磷蛹;copy()函數(shù)有返回值吮旅,會返回復(fù)制元素的個數(shù),即最小切片的長度
package main
import "fmt"
func main() {
a := [] int {1,2,3}
b := [] int {0}
copy(a,b)//復(fù)制b到a味咳,b中只有一個元素庇勃,a中只會更改第一個元素
fmt.Println(a)//輸出[0 2 3]
fmt.Println(b)//輸出[0]
aa := [] int {1,2,3}
bb := [] int {0}
copy(bb,aa)//復(fù)制aa到bb,bb的長度只有1槽驶,所以bb只會復(fù)制aa中的第一個元素
fmt.Println(aa)//輸出[1 2 3]
fmt.Println(bb)//輸出[1]
}
多維切片
切片也可以像數(shù)組一樣责嚷,有多維切片的存在
package main
import "fmt"
func main() {
//創(chuàng)建一個多維切片
a := [][] int {{1,2},{3}}
fmt.Println(a)//輸出[[1 2] [3]]
//給第一個切片追加一個元素
a[0] = append(a[0],8)
fmt.Println(a)//輸出[[1 2 8] [3]]
}
range
可以使用range語句遍歷數(shù)組和切片,for循環(huán)也可以用于遍歷掂铐,但是range語句可以返回索引和該索引處的值
package main
import "fmt"
func main() {
a := [...] int {1,2,3,4,5}
//如果希望去除索引罕拂,可以使用_替換i
for i,v := range a {
fmt.Printf("數(shù)組下標:%d,值:%d\n",i,v)
}
/*
輸出:
數(shù)組下標:0堡纬,值:1
數(shù)組下標:1聂受,值:2
數(shù)組下標:2蒿秦,值:3
數(shù)組下標:3烤镐,值:4
數(shù)組下標:4,值:5
*/
}