golang基础数据结构

hello world

// hello_world.go

package main

import "fmt"

func main (){
  fmt.Println('hello world')
}

运行cmd

go run hello_world.go

编译cmd

go build hello_world.go

会生成二进制文件,极其方便的进行系统环境迁移

golang 说明

程序入口main

package mainfunc main

数据类型

  • bool
  • string
  • Int int8. Int16 int32 int64
  • unit unit8. unit16. unit32. unit64. unitptr
  • byte. // alias for unit8
  • rune. // alias for int32, represent a unicode code point
  • float32 float64
  • complex64. complex128

完全不支持隐式类型转换

别名和原有类型也不支持隐式类型转换

golang测试

测试文件以_test.go 结尾表示测试文件

函数以Test开头表示测试函数

import 'testing'
func Testxxxxxx(t *testng.T) {
  // do sth
}

类型的预定义的值

有时候需要定义一些最大最小值的:比如

import "math"

math.MaxInt64
math.MaxFloat64
math.MaxUnit32 

指针类型

  • 不支持指针运算
  • string是值类型,其默认的初值是空字符串,而不是nil

获取指针:&

a:=1  // int
aPtr:= &a  // *int

运算符

和普通语言差不多

  • 不支持前置的自增,支持后置。例如。++a 是错误的

循环

golang支持for关键字

for j:=7;j<=9;j++ 

实现while

// while n < 5

for n<5 {
  n++
  fmt.Pringln(n)
}

// 无限循环 while true
for {
  ...
}

If 条件语句

和主流语言的if语句区别不大

if condition {
  ...
}else if condition {
  ...
}else {
  ...
}

主要差异

可以增加一段赋值

if var xxx;condition {
  ...
}

if a: 1 ==1;a{
  t.log(...)
}
// 方便支持go func的多返回值
if v,err:=somefun();err==nil {
   // do error
}else {
  // do right
}

switch 条件

  • 每个case 默认有break
  • 条件表达式不限制为常量和表达式以及整数
  • 单个case 允许多值,匹配一个就可以
  • 类似if语句作用

数组

声明

var a [3]int  // 声明并初始化默认值为 ‘零值’
a[0] = 1

b:=[3]int{1,2,3}  // 声明并同时初始化
c:=[2][2]int{{1,2},{3,4}} // 多维数组初始化

d:=[...]int{1,2,3,4,5} // 一开始不知道长度是多少

遍历

// 传统写法,不推荐
for i:=0;i<en(arr);i++{
  // do sth 
}

// 推荐写法
for idx, e := range arr {
  // idx 是索引,e是元素值。 类似python里面的枚举enumerate
}
// 不想要索引  使用占位符 下滑线  _
for _, e :range arr {
  // do sth
}

数组截取:切片

arr[start,end]  // 左闭右开

不支持负数索引,希望后面版本可以优化吧,python用起来爽死

切片 :slice

声明

// 声明数组
var a [3]int
// 声明切片slice, 和数组声明的区别
var s []int

// 初始化数组
b := [3]int{1,2,3}
// 初始化切片
d := []int{1,3,4}

使用make创建一个object

// 创建一个数组
a := make([3]int,3,5)
// 创建一个slice
b := make([]int,3,8)
make

初始化默认只会初始化length长度的初始值

但是可以继续append元素,只要容量还足够

切片数据结构

切片本质是一个共享的数据结构

lencap
var a := []int
for i=0;i<10;i++{
  a = append(a, i)  // 通过append为什么这么写,去理解capacity的变化,为啥每次重新赋值,扩容之后地址发生了变化
  t.Log(len(a), cap(a))
}

slice 比数组更灵活,自动扩容

带来的是数据搬移的性能损耗

共享数据结构!!!!

如果指定一段连续的空间,进行切片,那capacity就是从开头位置到这片连续存储空间的结束

y:=[]string{"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"}
q1:=y[3:6]
t.Log(q1, len(q1), cap(q1)) // ["apr","may","jun"]  3  9   注意capacity
q2:=y[5:8]
t.Log(q2, len(q2), cap(q2)) // ["jun","jul","aug"]   3  7   

如果对切片进行更改,会影响到其他切片的值——共享内存空间

数组可以相同长度进行比较,切片只能和nil进行比较,相同长度也无法比较