Go数据结构篇

程序小偷 · · 396 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1、基本数据类型
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // alias for int8
rune // alias for int32,represents a Unicode code point
float32 float64
complex64 complex128

package try_test

import (
    "fmt"
    "testing"
)

func TestTry(t *testing.T) {
    t.Log("hello world!")
}

func TestFibList(t *testing.T) {
/*  var a int = 1
    var b int = 1*/
/*  var (
        a int = 1
        b int = 1
    )*/
    a := 1
    b := 1
    fmt.Print(a)
    for i := 0; i < 5; i++ {
        fmt.Print(" ", b)
        tmp := a
        a = b
        b = tmp + a
    }
    fmt.Println()
}

常量定义

package constant_test

import "testing"

const (
    Monday = 1 + iota
    Tuesday
    Wednesday
)

const (
    Readable = 1 << iota
    Writable
    Executable
)

func TestConstantTry(t *testing.T) {
    t.Log(Monday, Tuesday, Wednesday)
}

func TestConstantTry1(t *testing.T) {
    a := 1 //0001
    t.Log(a&Readable == Readable, a&Writable == Writable, a&Executable == Executable)
}

2、类型转换
(1)Go语言不允许隐式类型转换(不支持小位数类型向大位数类型转)
(2)别名和原有类型也不能进行隐式类型转换(type MyInt int64 => int64)

3、类型的预定义值
1.math.MaxInt64
2.math.MaxFloat64
3.math.MaxUInt32

4、指针类型
(1)不支持指针运算
(2)string是值类型,其默认的初始化值为空字符串,而不是nil

5、算术运算符
+ - * / % ++ --(不支持前置++ --)

6、比较运算符
#== != > < >= <=
(1)比较数组
相同维数且含有形同个数元素的数组才可以比较
每个元素都相同的才相等

7、位运算符
& | ^ << >>
&^ (按位置零) a & (^b)
1 &^ 0 1
1 &^ 1 0
0 &^ 1 0
0 &^ 0 0

8、条件与循环
(1)循环
Go 语⾔仅⽀持循环关键字 for

func TestWhileLoop(t *testing.T) {
    n := 0
    for n < 5 {
        t.Log(n)
        n++
    }
/*  for {
        t.Log("无限循环")
    }*/

}

(2)条件

  1. condition 表达式结果必须为布尔值
  2. ⽀持变量赋值:
    if var declaration; condition {
    // code to be executed if condition is true
    }
    3.switch
  3. 条件表达式不限制为常量或者整数;
  4. 单个 case 中,可以出现多个结果选项, 使⽤逗号分隔;
  5. 与 C 语⾔等规则相反,Go 语⾔不需要⽤break来明确退出⼀个 case;
  6. 可以不设定 switch 之后的条件表达式,在此种情况下,整个 switch 结
    构与多个 if…else… 的逻辑作⽤等同
func TestSwitchMultiCase(t *testing.T) {
    for i := 0; i < 5; i++ {
        switch i {
        case 0, 2:
            t.Log("Even")
        case 1, 3:
            t.Log("Odd")
        default:
            t.Log("it is not 0-3")
        }
    }
}

func TestSwitchCaseCondition(t *testing.T) {
    for i := 0; i < 5; i++ {
        switch {
        case i%2 == 0:
            t.Log("Even")
        case i%2 == 1:
            t.Log("Odd")
        default:
            t.Log("unknow")
        }
    }
}

9、数组和切片
数组截取,索引下标从0开始计数
a[开始索引(包含), 结束索引(不包含)]
a := [...]int{1, 2, 3, 4, 5}
a[1:2] //2
a[1:3] //2,3
a[1:len(a)] //2,3,4,5
a[1:] //2,3,4,5
a[:3] //1,2,3

package array_test

import "testing"

func TestArrayInit(t *testing.T) {
    var arr [3]int // 声明并初始化为默认0值
    arr1 := [4]int{1, 2, 3, 4} // 声明同时初始化
    arr2 := [2][2]int{{1,2},{3,4}} // 多维数组初始化
    arr3 := [...]int{1, 3, 4, 5}
    arr1[1] = 5
    t.Log(arr[1], arr[2])
    t.Log(arr1, arr2, arr3)
}
// 数组遍历
func TestArrayTravel(t *testing.T) {
    arr3 := [...]int{1, 3, 4, 5}
    for i := 0; i < len(arr3); i++ {
        t.Log(arr3[i])
    }
    for idx, v := range arr3 {
        t.Log(idx, v)
    }
    for _, e := range arr3 {
        t.Log(e)
    }
}
//数组截取
func TestArraySection(t *testing.T) {
    arr3 := [...]int{1, 2, 3, 4, 5}
    arr3_sec := arr3[:]
    t.Log(arr3_sec)
}

切片内部结构


image.png
package slice_test

import "testing"

func TestSliceInit(t *testing.T) {
    var s0 []int  //声明切片
    t.Log(len(s0), cap(s0))
    s0 = append(s0, 1)
    t.Log(len(s0), cap(s0))

    s1 := []int{1, 2, 3, 4} //声明切片并初始化
    t.Log(len(s1), cap(s1))

    s2 := make([]int, 3, 5)//指定长度和容量声明切片
    t.Log(len(s2), cap(s2))
    t.Log(s2[0], s2[1], s2[2])
    s2 = append(s2, 1)//增加值(长度会变化,容量会超出会成倍增加)
    t.Log(s2[0], s2[1], s2[2], s2[3])
    t.Log(len(s2), cap(s2))
}

func TestSliceGrowing(t *testing.T) {
    s := []int{}
    for i := 0; i < 10; i++ {
        s = append(s, i) //增加值(长度会变化,容量超出会成倍增加)
        t.Log(len(s), cap(s))
    }
}

func TestSliceShareMemory(t *testing.T) {
    // 切片共享存储结构
    year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
        "Oct", "Nov", "Dec"}
    Q2 := year[3:6]
    t.Log(Q2, len(Q2), cap(Q2))
    summer := year[5:8]
    t.Log(summer, len(summer), cap(summer))
    summer[0] = "Unknow"
    t.Log(Q2)
    t.Log(year)
}

func TestSliceComparing(t *testing.T) {
    a := []int{1, 2, 3, 4}
    b := []int{1, 2, 3, 4}
    // if a == b { //切片只能和nil比较
    //  t.Log("equal")
    // }
    t.Log(a, b)
}

9、Map

package my_map

import "testing"

func TestInitMap(t *testing.T) {
    m1 := map[int]int{1: 1, 2: 4, 3: 9}
    t.Log(m1[2])
    t.Logf("len m1=%d", len(m1))
    m2 := map[int]int{}
    m2[4] = 16
    t.Logf("len m2=%d", len(m2))
    m3 := make(map[int]int, 10)
    t.Logf("len m3=%d", len(m3))
}

func TestAccessNotExistingKey(t *testing.T) {
    // 区分key是0值还是不存在
    m1 := map[int]int{}
    t.Log(m1[1])
    m1[2] = 0
    t.Log(m1[2])
    m1[3] = 0
    if v, ok := m1[3]; ok {
        t.Logf("Key 3's value is %d", v)
    } else {
        t.Log("key 3 is not existing.")
    }
}

func TestTravelMap(t *testing.T) {
    // map遍历
    m1 := map[int]int{1: 1, 2: 4, 3: 9}
    for k, v := range m1 {
        t.Log(k, v)
    }
}
package map_ext

import "testing"

func TestMapWithFunValue(t *testing.T) {
    // map与工厂模式
    m := map[int]func(op int) int{}
    m[1] = func(op int) int { return op }
    m[2] = func(op int) int { return op * op }
    m[3] = func(op int) int { return op * op * op }
    t.Log(m[1](2), m[2](2), m[3](2))
}

func TestMapForSet(t *testing.T) {
    // map实现set
    mySet := map[int]bool{}
    mySet[1] = true
    n := 3
    if mySet[n] {
        t.Logf("%d is existing", n)
    } else {
        t.Logf("%d is not existing", n)
    }
    mySet[3] = true
    t.Log(len(mySet))
    delete(mySet, 1)
    n = 1
    if mySet[n] {
        t.Logf("%d is existing", n)
    } else {
        t.Logf("%d is not existing", n)
    }
}

9、字符串

  1. string 是数据类型,不是引⽤或指针类型
  2. string 是只读的 byte slice,len 函数可以返回它所包含的 byte 数
  3. string 的 byte 数组可以存放任何数据

Unicode UTF8

  1. Unicode 是⼀种字符集(code point)
  2. UTF8 是 unicode 的存储实现 (转换为字节序列的规则)


    image.png

常⽤字符串函数

  1. strings 包 (https://golang.org/pkg/strings/)
  2. strconv 包 (https://golang.org/pkg/strconv/)
package string_test

import (
    "testing"
)

func TestString(t *testing.T) {
    var s string
    t.Log(s) //初始化为默认零值“”
    s = "hello"
    t.Log(len(s))
    //s[1] = '3' //string是不可变的byte slice
    //s = "\xE4\xB8\xA5" //可以存储任何二进制数据
    s = "\xE4\xBA\xBB\xFF"
    t.Log(s)
    t.Log(len(s))
    s = "中"
    t.Log(len(s)) //是byte数

    c := []rune(s)
    t.Log(len(c))
    //  t.Log("rune size:", unsafe.Sizeof(c[0]))
    t.Logf("中 unicode %x", c[0])
    t.Logf("中 UTF8 %x", s)
}

func TestStringToRune(t *testing.T) {
    s := "中华人民共和国"
    for _, c := range s {
        t.Logf("%[1]c %[1]x", c)
    }
}
package string_test

import (
    "strconv"
    "strings"
    "testing"
)

func TestStringFn(t *testing.T) {
    // 切割与连接
    s := "A,B,C"
    parts := strings.Split(s, ",")
    for _, part := range parts {
        t.Log(part)
    }
    t.Log(strings.Join(parts, "-"))
}

func TestConv(t *testing.T) {
    // int转string
    s := strconv.Itoa(10)
    t.Log("str" + s)
    // str转int
    if i, err := strconv.Atoi("10"); err == nil {
        t.Log(10 + i)
    }
}


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:程序小偷

查看原文:Go数据结构篇

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

396 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传