Go-复合数据类型

复合数据类型

1.数组

数组是具有相同数据类型的数据项组成的一组长度固定的序列,数据项叫做数组的元素,数组的长度必须是非负整数的常量,长度也是类型的一部分

1.1声明

数组声明需要指定组成元素的类型以及存储元素的数量(长度)。在数组声明后,其长度不可修改,数组的每个元素会根据对应类型的零值对进行初始化

package main

import "fmt"
func main() {
  var names [10]string
  var scores [10]int

  fmt.Printf("%T, %T\n",names,scores)
  fmt.Printf("%q\n",names)
  fmt.Println(scores)

}
#索引  
package main

import "fmt"

func main() {
     var abc [10]int = [10]int{2:1000}
     fmt.Println(abc)
} 
#索引 0 > len-1 
#0 1 2  
索引打印的值为  [0 0 1000 0 0 0 0 0 0 0]

索引赋值  
顺序赋值 [lenght]type{v1,v2,v3.......} 
索引    [lenght]type{i1:v1,i2,v2....}

1.2字面量

*指定数据的长度

*使用初始化元素数量推到数组长度

*对指定位置元素进行初始化

package  main

import "fmt"

func main(){

   var names[10] string
   var scores [5]int = [5]int{1,2,3,4,5}  //数组赋值,字面量  
   fmt.Printf("%T\n",names)
   fmt.Printf("%q\n",names)
   fmt.Printf("%T\n",scores)

   fmt.Println(names,scores)
}

1.2 数组操作

*关系运算== 、!=

package  main

import "fmt"

func main(){

   var names[10] string
   var scores = [...]int{100,88}  //数组赋值,字面量
   fmt.Println(names,scores)

   //运算
   var  nums [2]int = [...]int{88,100}
   fmt.Println(nums == scores)


}
1.2.1 字面量访问

*访问值通过索引


package  main

import "fmt"

func main(){
	var scores = [...]int{100,88}  //数组赋值,字面量
	var  nums [2]int = [...]int{88,100}
  //运算
	fmt.Println(nums == scores)
  
	//访问
	fmt.Println(nums[0])
	nums[0] = 101
	nums[1] = 102
	fmt.Println(nums)
  
  //赋值
   nums[0] = 101
   nums[1]  = 102
   fmt.Println(nums[0])
   fmt.Println(nums[1])
  
}
1.2.2 数组长度

*使用len函数可以获取数组的长度

fmt.Println(len(nums))
1.2.3 元素访问(遍历)
方法一:   
for i :=0; i < len(nums); i++ {
      	fmt.Println(i,nums[i])
	  }

方法二:
for   v := range nums {
	  	fmt.Println(v,nums[v])
	  }

方法三:
for  i, v := range nums{
	    	fmt.Println(i,v)
		}

2. 切片

*切片是长度可变的数组(具有相同数据类型的数据项组成的一组长度可变的序列),切片由三部分组成:

  1. 指针: 指向切片第一个元素指向元素的地址
  2. 长度: 切片元素的数量
  3. 容量: 切片开始到结束位置元素的数量

2.1 声明

*切片声明需要指定组成元素的类型,但不需要指定存储元素的数量(长度),在切片声明后,会被初始化为nil,表示暂不存在的切片

package main

import "fmt"

func main(){

   var  names []string

   fmt.Printf("%T\n",names)
   fmt.Printf("%v\n",names)

}

2.2 初始化

//初始化值
names = []string{"xingxing","123"}

fmt.Printf("%T\n",names)
fmt.Printf("%q\n",names)

2.3 字面量

//字面量
//[]type{}=> 空切片
//[]type{v1,v2,v3......}
//[]type{i1:v1,i2:v2....}
names =[]string{1:"golang", 10:"123"}
fmt.Printf("%T\n",names)
fmt.Printf("%q\n",names)

2.4 元素访问

//访问  修改元素
//索引
fmt.Println(names[1])
fmt.Println(names[10])
fmt.Println(names[8])
names[8]="学习go" //修改
fmt.Println(names)

2.5 长度与遍历

fmt.Println(len(names))
//长度,切片中已经存在元素的数量

//遍历
for i := 0;i<len(names);i++{
   fmt.Println(i,names[i])
}
    
for v := range names{
     	fmt.Println(v,names[v])
	 }

for  i, v := range names{
   fmt.Println(i,v)
}

2.6 添加元素

//添加元素,是给末位添加
names = append(names,"测试添加")
fmt.Println(names)

2.7 删除元素

//删除元素
//切片操作
//names[start:end] names 中从start开始到end-1 所有元素组成的切片
fmt.Printf("%q\n",names[1:10])

//删除索引为0,如果索引为len-1元素
names = names[1:len(names)]
fmt.Printf("%q\n",names)

names = names[0:len(names)-1]
fmt.Printf("%q\n",names)


//删除中间的元素
 nums :=[]int{0,1,2,3,4,5}
//删除3
 nums2 :=[]int{10,11,12,13,14,15,16}
 copy(nums,nums2)
 fmt.Println(nums,nums2)
 //nums[0:3],nums[4:5]
 //nums2 多
 copy(nums,nums2)
 fmt.Println(nums,nums2)
 
 //nums[0:3],nums[4:5]
 copy(nums[3:len(nums)],nums[4:len(nums)])
 fmt.Println(nums)
#切片底层共享数组

2.8 make 函数

package main

import "fmt"

func main(){
   //make
   // 2个参数: make(type,len)
   // 3个参数: make(type,len,cap)
   //  
   nums := make([]int,3)
   fmt.Println(len(nums),cap(nums))
   fmt.Println(nums)
   
  //指定len 与cap 
   nums2 := make([]int,2,5)
   fmt.Println(len(nums2),cap(nums2))
   fmt.Println(nums2)

   nums3 := nums2
   nums3 = append(nums3,4)
   nums2 = append(nums2,4)
   fmt.Println(nums3)
   fmt.Println(nums2)

   //变量赋值的时候是复制的方式
}
package main

import "fmt"

func main() {
   //复制nums 中的所有数据到nums2(两个不会有相互影响)
   //第一种方法
   //nums := []int{1,2,3,4,5}
   //nums2 :=[]int{}
   //copy(nums2,nums)
  
   //第二种方法
   //nums := []int{1,2,3,4,5}
   //nums2 := make([]int,len(nums))
   //for i, v := range nums {
   // nums2[i] = v
   //}
   //fmt.Println(nums2)

   //第三种方法
   nums := []int{1, 2, 3, 4, 5}
   nums2 := make([]int, 0, len(nums))
   // 空白标识符
   for _, v := range nums {
      nums2 = append(nums2, v)
   }
       fmt.Println(nums2)

}

2.9 容量

package main

import "fmt"

func main() {
   nums := []int{1,2,3,4,5}
   fmt.Println(len(nums),cap(nums))
   nums = append(nums,6)
   fmt.Println(len(nums),cap(nums))
    nums= append(nums,7)
    fmt.Println(len(nums),cap(nums))
    nums = append(nums,8)
    fmt.Println(len(nums),cap(nums))
    
}
package main

import "fmt"

func main() {
  // 复制nums 中所有数据到nums2
	//第一种方法
	//nums := []int{1,2,3,4,5}
	//nums2 := []{}
	//copy(nums2,nums)
   
  /* 第二种方法
	 nums  := []int{1,2,3,4,5}
	 nums2 := make([]int,len(nums))
	 for i, v := range nums {
	 	nums2[i] =v
	 }
    fmt.Println(nums2)*/

	nums := []int{1,2,3,4,5}
	nums2 := make ([]int,0,len(nums))
	for _,v := range nums {
	nums2 = append(nums2,v)
	}
	fmt.Println(nums2)

}
//容量的计算
package main

import "fmt"

func main() {
   //nums := []int{1,2,3,4,5}
   nums := make([]int,5,100)
   // slice[start:end]
   // 0 <= start  <=  end  <= cap
   // len := end-start
   // cap := cap - start
   nums2 := nums[10:100]
   fmt.Println(nums2)
    fmt.Println(nums2,len(nums2),cap(nums2))

}

2.10 切片的解包操作

package main

import "fmt"

func main() {
   nums :=[]int{1,2,3}
   nums2 :=[]int{3,4,5}


   nums = append(nums,100,102,105)
   fmt.Println(nums,nums2)

   /*for _, v:=range nums2 {
      nums = append(nums,v)
   }
      fmt.Println(nums,nums2)
   */
    // 切片解包
   nums = append(nums,nums2...)
   fmt.Println(nums,nums2)



}

2.11 队列与堆栈

队列

package main

import "fmt"

func main(){
   //队列
   //先进先出
   queue := []int{}
   queue = append(queue,1)
   queue = append(queue,2)
   queue = append(queue,3)
   queue = append(queue,4)
   queue = append(queue,5)
   queue = append(queue,6)
   //append  右边进入
   // 1 - > [1]
   // 2 ->  [2]
   // 3 -> [1,2,3]
   //从左边出
   //<- 1 [2,3]
   //<- 2 [3]
   //< -3 []

   for len(queue) != 0{
      fmt.Println(queue[0])
      queue = queue[1:]
   }
       fmt.Println("over")
}

堆栈

package main

import "fmt"

func main(){
   stack := []int{}
   //先进后出
   //append 从右边进入
   // 1 -> [1]
   // 2 -> [2]
   // 3 -> [3]
   // 从左边出
   // 3,2,1
   stack = append(stack ,1)
   stack = append(stack,2)
   stack = append(stack,3)
   for len(stack)  !=0 {
      fmt.Println(stack[len(stack)-1])
      stack = stack[:len(stack)-1]
   }


}

3. 浮点数

带小数的,非精确的

字面量

十进制表示法: 3.1415926 

科学记数法:  Le-5
package main

import "fmt"

func main() {

   height := 1.169

   fmt.Printf("%T,%f,%g,%e\n",height,height,height,height)
    //运算
    //算数运算
    //关系运算 >,>=,<,<=
    //赋值运算
    fmt.Println(1.2+1.1 )
   fmt.Println(1.2-1.1)
   fmt.Println(1.2*1.1)
   fmt.Println(1.2/1.1)
   //类型转换  float64()
}

4.字符串

go语言内置了字符串类型,使用string 表示

字面量
****可解析字符串: 通过双引号(")来创建,不能包含多行,支持特殊字符转义序列 
****原生字符串:通过反引号(`)来创建,可包含多行,不支持特殊字符穿衣序列
package main

import "fmt"

func main() {
    var  name   string = `xingxing`
    fmt.Printf("%T,%s\n",name,name)

    name += "hi"
    fmt.Println(name)
    name = "我爱中国"
    //索引
    fmt.Printf("%T\n",name[0])
    //长度
    fmt.Println(len(name))
    //切片
    fmt.Println(name[0:4])

}
package main

import (
   "fmt"
   "unicode/utf8"
)

func main() {
    var  name string  = "xingxing"
    var  desc string ="i love china"
    // 字面量
    // 零值
    // 操作
    // 连接
    // 关系运算
    // 索引,字节
    // 切片 => 字符串,字节

    fmt.Println(name,desc)
    fmt.Println(desc[1:5])

    for i, v := range  desc {
       fmt.Println(i,v)
   }

   var  txt = "我爱中国"
   for i , v := range txt {
      fmt.Printf("%d,%q\n", i,v )
   }
   fmt.Println(utf8.RuneCountInString(txt))  // 打印字节
   

}
语法 描述/结果
s += t 将字符串t 追加到字符串s 末尾
s[n] 字符串s中索引位置为n 处的原始字节
s[n:m] 从位置n到位置m-1处取得的字符串
s[n:] 从位置n到位置len(s)-1处取得的字符串
s[:m] 从索引位置0到位置m-1处取得的字符串
len(s) 字串符s中的字节数

5 流程控制

条件语句(if-elase if-else) 或选择语句(switch case)及循环语句(for)

package main

import "fmt"

func main() {

   var score int

   fmt.Print("请输入成绩:")
   fmt.Scan(&score)

   if score >= 90 {
      fmt.Println("A")
   } else  if score >= 80 {
      fmt.Println("B")
   } else if score  >= 60 {
      fmt.Println("C")
   }

}
package main

import "fmt"

func main() {
     var  score int
     fmt.Print("请输入成绩:")
     fmt.Scan(&score)

     switch  {

    case score  >= 90:
      fmt.Println("A")
    case score  >= 80:
      fmt.Println("B")
    case score  >=70:
      fmt.Println("C")
    default:
        fmt.Println("E")
    }

}

6 类型转换

类型转换格式 [:] =()

package main

import "fmt"

func main() {
   var   c   float32 = 100.1
   fmt.Println(c)
   d  := int(c)
   fmt.Println(d)
}

结果:100 
package main

import (
   "fmt"
   "strconv"
   "unicode/utf8"
)
func main() {
   var  name string = "xingxing"
   var  desc string = "i love china "
   // 字面量 "" ``
   // 零值
   // 操作
   // 连接
   // 关系运算
   // 赋值操作
   // 长度len 字节长度
   // 索引  字节
   // 切片= 字符串   字节

   fmt.Println(name,desc)
   fmt.Println(desc[1:5])

   var   txt  = "我爱中国"

   for i,v := range txt {
      fmt.Printf("%d,%q\n",i,v)
   }
     fmt.Println(utf8.RuneCountInString(txt))

   //转换 字符串=> byte
   fmt.Println([]byte(desc))
   fmt.Println(string([]byte(desc)))

   // 字符串<=> int
   i, err  := strconv.Atoi("-15")
   fmt.Println(i,err)
   // 字符串<=> bool
}

7 指针类型

每个变量在内存中都有对应存储位置(内存地址),可以通过& 运算符获取。指针是用来存储变量地址的变量

package main

import "fmt"

func main() {
	//指针
	//值类型
	//赋值  原有的数据复制一份给新的变量
	//两个变量之间没有任何关系
	//对nums 进行修改都不会影响nums2
	//对nums2 进行任何修改也不会影响nums
	nums := [5]int{1,2,3,4,5}
	nums2 := nums
	fmt.Println(nums,nums2)

	nums2[0] = 100
	fmt.Println(nums,nums2)

	var  age = 1
	var  agePointer *int
	fmt.Println(age,agePointer)


	agePointer = &age
	fmt.Println(agePointer,age)

	fmt.Println(*agePointer)

	*agePointer = 33
	fmt.Println(age,*agePointer)

	var numsPoint   = &nums
	fmt.Printf("%T\n",numsPoint)

	numsPoint[0] = 100
	fmt.Println(nums,numsPoint)

}
comments powered by Disqus