go语言学习--基础篇(3)

一,go语言数组

     1,数组的特点

          a. 数组在初始化完成之后,数组的长度是固定的

             b. 只存储同一类型的数据

             c. 数组中的元素与元素之间的内存空间是连续的

      2,数组的定义

             var a [5]int     其中a 表示数组的名称,[5]表示数组的长度,int 表示数组中的元素类型

      3,数组中元素的访问

              使用下标访问 a[0],a[1],a[2]

      4,循环获取数组每个元素的地址

package main

import (

       "fmt"
)

func main() {

       var a [10]int
       for i :=0;i <10; i++{
             fmt.Printf("%p\n", &a[i]}

    }
}


输出结果:                                        #明显每个元素占8个字节,而且是连续的
0xc04206e050                                    #int 类型所占的内存空间和操作系统有关 64位操作系统,int 占64位,即8个字节
0xc04206e058                                     
0xc04206e060
0xc04206e068
0xc04206e070
0xc04206e078
0xc04206e080
0xc04206e088
0xc04206e090
0xc04206e098

        5,数组长度

             var  a[10]int   length := len(a)

         6,数组存在越界问题

              var  a[10]int 长度为10,下标范围为0到9。访问0到9之外的小标会报错

         7,数组的遍历

/* range 遍历数组 */
package main
import (
	"fmt"
)
func main() {

	var a [10]int
	for index,val := range a{
		fmt.Printf("a[%d] = %d\n",index,val)
	}
}

 

           8, 值类型

func test() {

     var a [5]int = [5]int {1,2,3,4,5}
     var b [5]int
     b = a
     fmt.Printf("b=%v\n",b)
     b[0] = 200     
     fmt.Printf("b=%v\n",b)
     fmt.Printf("a=%v\n",a)
}

#输出结果为
#b=[1 2 3 4 5]
#b=[200 2 3 4 5]
#a=[1 2 3 4 5]
#从中可以看出改变数组b中的元素,并不会改变数组a中的元素,这就是值类型

        9,数组的初始化

              a. var a[5] int = [5]int {1,2,3,4,5}

              b. var a = [5]int{1,2,3,4,5}

              c. var a = [...]int{1,2,3,4,5}  其中[...]表示不确定长度

              d. var a = [5]string{1:"abc",2"eft"}  表示给数组a的前两个元素赋值为a[0]=abc,a[1]=eft

      10,二维数组定义

              var a[8][2]int   定义一个8行2列的数组

 

二,切片

     切片的长度是动态的,任何切片底层都为数组

      1,切片的定义, 与数组的定义唯一的区别就是没有长度,并且默认长度为0

            var  变量名 [ ] type

           a. var  a [] string

           b. var  a [] float32

      2,切片的初始化(切片为引用类型)

           var  a [5] int

           var  b []int = a [0:2]

           var  b []int = a [2:]

           var  b []int = []int{1,2,3,4,5}

     3,示例思考

         可以看出a 的值改变,相应的切片b的值也会变,说明切片为指针类型或者引用类型

package main

import(
	"fmt"
)

func main(){

	var a [5]int
	b :=a[1:3]
	a[0] =100
	a[1] =200
	fmt.Printf("b:%#v\n",b)                         
}

输出为:
b:[]int{200,0}

          4,切片的内存布局

               x 为一个切片,切片的形式包含三个内容,指向底层数组的指针,定义切片的长度和切片的容量

           5,传数组与传切片

package main

import (
	"fmt"
)

func Sum(b []int){
	b[0] = 100
}

func SumArry(b [100]int){
	b[0] = 100
}

func main(){

	var a [100]int
	a[0] = 1
	a[1] = 2
	a[2] = 3

	Sum(a[:])
	fmt.Printf("a:%d\n",a[0])
	a[0] = 1                                                #重置a[0]的值
	SumArry(a)
	fmt.Printf("a:%d\n",a[0])
}

#输出为                                  
#a:100
#a:1
#从输出结果可以看出 传入参数为切片时,底层数组的值可以被改变,当传入是数组时,数组的值不能改变,#再次说明切片为指针类型或者引用类型,而数组为数值类型

           6,切片的创建

            var  b []int

            b = make([]int,5,10)

            a. 指定切片容量 make([]type,len,cap)

            b. 不指定切片容量,容量就等于长度 make([]type,len),

            注意:

                  以make 方式创建一个数组,其底层也一个数组,有make 创建

           

            7,切片的内存操作copy 和 append 操作,append 会对切片进行扩容,增加内存

            将一个切片append 到另一个切片 

func testAppend(){
         var a []int
         a = make([]int,5)
         var b[]int = []int{10,11,12,14}
         a =append(a,b...)                       #b... 展开切片b的所有元素
         ftm.Printf("a:%#v\n",a)
}

 

          8,字符串的内存布局

           在go 语言中,字符串也是一个切片,内存布局如下图

            a,ptr 为指针

            b,len为长度,

            c,容量也就是长度

            d,类型为byte

  

          9,修改字符串中某个字符

func testStrSlice() {
          var str = 'hello world"
          var b []byte = []byte(str)                   #请字符串转化成切片
          b[0] = 'a'                                         #修改切片第一个值
          str1 :=string(b)                                 #将切片转化成string
          fmt.Printf("str1:%s\n",str1
}

 

 

 

           

posted @ 2017-12-14 16:09  niu_x  阅读(245)  评论(0编辑  收藏  举报