Golang 基础 - 数据类型

Golang 基础 - 数据类型

基本数据类型

类型关键字
整型intbyte int8int16rune int32int64 uint uint8 uint16 uint32 uint
浮点型float32(精度7位) float64(精度16位)
字符型rune
错误error
字符串string
布尔型bool

fmt.Printf 的一些常用占位符

占位符作用
%T取类型
%d十进制数
%b二进制数
%s字符串
%t布尔值
%p内存地址
%f浮点数
%e科学计数法

整型、浮点型

除了 byte 表示 int8 、rune 表示 int32 以及 ++ 和 – 只能单独存在外,其它的不用多说了,上示例:

import (
	"fmt"
)

func main() {
    var num_byte byte = 1
	var num_int8 int8 = 1
	var num_rune rune = 1
	var num_int32 int32 = 1
	// num_byte = int8, num_int8 = int8, num_rune = int32, num_int32 = int32
	fmt.Printf("num_byte = %T, num_int8 = %T, num_rune = %T, num_int32 = %T\n", num_byte, num_int8, num_rune, num_int32)

	// Golang 有加(+)减(-)乘(*)除(/)取余(%)自加(++)自减(--) 7 种算数运行符
	var numA int32 = 2
	numA++ // Golang 中 ++numA 为错误语法
	fmt.Println(numA) // 3
	numA-- // Golang 中 --numA 为错误语法
	fmt.Println(numA) // 2
}

字符串、字符

Golang 的字符串是不可变的,上示例:

import (
	"fmt"
)

func main() {
	// Go 语言的字符串使用双引号("")或者反引号(``)
	str := "ABCDE"
	// str = (string, ABCDE)
	fmt.Printf("str = (%T, %s)\n", str, str)

	strA := "A"
	charA := 'A'
	// Golang 的字符类型(rune)就是32位整型(int32)
	// strA = (string, A), charA = (int32, A)
	fmt.Printf("strA = (%T, %s), charA = (%T, %c)\n", strA, strA, charA, charA)

	// Golang 的语言使用 UFT-8 编码,中文占 3 个字节
	zhStr := "你好,世界"
	// 因为中文占 3 个字节,所以使用 len 方法将输出 13
	// zhStr = (string, 13)
	fmt.Printf("zhStr = (%T, %d)\n", zhStr, len(zhStr))
	// 使用 unicode/utf8 包提供的 RuneCountInString 方法获取字符的数目
	// zhStr = (string, 5)
	fmt.Printf("zhStr = (%T, %d)\n", zhStr, utf8.RuneCountInString(zhStr))
	// 或者使用 rune 类型处理(数据类型的转换)
	// zhStr = (string, 5)
	fmt.Printf("zhStr = (%T, %d)\n", zhStr, len([]rune(zhStr)))
}

布尔型

布尔型只有 truefalse 和其它语言一样都有一些关系运算符,上示例:

import (
	"fmt"
)

func main() {
	fmt.Println(true && true, true)
    fmt.Println(true && false, false)
    fmt.Println(false && true, false)
    fmt.Println(false && false, false)
    fmt.Println(true || true, true)
    fmt.Println(true || false, true)
    fmt.Println(false || true, true)
    fmt.Println(false || false, false)
    fmt.Println(!true, false)
    fmt.Println(!false, true)
}

错误

错误 (error) 是 Golang 的内置类型本质上是一个接口

type error interface {
    Error() string
}

示例:

import (
	"fmt",
    "errors"
)

func main() {
    fmt.Println(errors.New("Hello Error")) // Hello Error
}

复合数据类型

类型说明
array数组
slice切片
map字典
function函数
interface接口
channel通道
pointer指针

数组

Golang 的数组的声明和其它语言不太一样,中括号[]既不是写在变量名的后面,也不是写在类型的后面,而是写在类型的前面,语法为

var 变量名 [长度]数据类型

示例:

import (
	"fmt"
)

func main() {
    // 声明一个长度为 5 的数组
    var arrayA [5]int
    // 数组会使用默认值进行填充,使用索引进行访问和修改
    arrayA[3] = 1
    // 也可以在声明时一同进行初始化
    arrayB := [5]int{1,2,3} // 1,2,3,0,0
    // 或者使用指定索引
    arrayC := [5]int{1:1,3:2} // 0,1,0,2,0
    // 使用 ...代替长度会自动填充长度
	arrayD := [...]int{1,2,3,4} // 长度为4
    arrayE := [...]int{2:1,6:2} // 长度为 7
}

遍历数组:

import (
	"fmt"
)

func main() {
    array := [...]int{1,2,3,4,5}
    
    // 使用 fori 循环遍历
    for i := 0; i < len(array); i++ {
        fmt.Printf("array[%d] = %d\n", i, array[i])
    }
    
    for index, value := range array {
        fmt.Printf("array[%d] = %d\n", index, value)
    }
}

多维数组和其它语言类似

import (
    "fmt"
)

func main() {
    array := [][]int{{1,2,3},{4,5,6},{7,8,9}}
    for _, arr := range array {
        for _, value := range arr {
            fmt.Printf("%d ", value)
        } 
		fmt.Println()
    }
}

切片

Golang 的数组和大部分的编程语言类型,都是在声明大小后就不能够再对大小进行改变,所以就有了切片slice的出现,切片的声明和数组类似,不过不需要指定长度:

var 切片名 []数据类型

切片有两个重要属性值,一个是长度使用 len 方法,一个是容量使用 cap 方法

通过使用 make 方法可以对这两个值进行初始化

make([]数据类型, 长度[,容量])

容量可以不传,默认和长度一样大

使用内置的append方法在切片的末尾追加元素

append 方法当容量足够时,不会创建一个新的地址,而当容量不够时则会创建一个新的地址,且新的切片容量为之前的两倍,前提都是左右两边操作的切片都相同,即 slice = append(slice, [元素]...)

import (
	"fmt"
)

func main() {
	var slice1 []int
    var slice2 []int
    slice2 = append(slice1, 1, 2, 3)
    fmt.Println(slice1) // []
    fmt.Println(slice2) // [1,2,3]
}

Golang 没有提供具体的删除切片元素的方法,一般通过使用获取切片片段来代替删除,示例

func main() {
	slice := []int{1,2,3,4}
	slice = slice[:] // slice = [1,2,3,4]
	slice = slice[1:] // slice = [2,3,4]
	slice = slice[:2] // slice = [2,3]
	// slice 的地址会发生改变
}

字典(map)

Golang 的 map 是无序的,不能通过下标获取,只能通过 key 访问对应的值

import (
	"fmt"
)

func main() {
    var map1 map[string]int // 声明一个key类型为字符串,value类型为int的map,没有初始化化,map1 为 nil
    map2 := make(map[string]int) // 声明并创建一个key类型为字符串,value类型为int的map,没有初始化化,map2 不为 nil
    map3 := map[string]int{"WenFlower": 99, "Wen": 60, "Flower": 59} // 声明并初始化map
    
    fmt.Println(map1 == nil) // true
    
    // 存储键值对到 map
    map2["WenFlower"] = 99
    
    // 获取key对应的value
    fmt.Println(map3["WenFlower"]) // 99
    
    // 获取 key 对应的值,以及是否存在对应的值 ok 为 true 表示存在,false 表示不存在
    value, ok := map3["WenFlower"]
    fmt.Println(value, ok) // 99, true
    
    // 删除对应的key
    delete(map3, "WenFlower")
    value, ok = map3["WenFlower"]
    fmt.Println(value, ok) // 0, false
    
    // 获取 map 的长度
    fmt.Println(len(map3)) // 2
    
    // 遍历 map
    for key, val := range map3 {
        fmt.Printf("map[%s] = %d\n", key, val)
    }
}

sync.Map

Golang 在 1.9 后提供的一个线程安全的键值对结构,但是使用几乎和 map 数据类型毫不相干

import (
	"fmt"
    "sync"
)

func main() {
    // 声明 sync.Map 就能直接使用
    var syncMap sync.Map
    
    // 存储key
    syncMap.Store("WenFlower", 99)
    syncMap.Store("Wen", 60)
    syncMap.Store("Flower", 59)
    
    // 获取 key 值
    fmt.Println(syncMap.Load("WenFlower")) // 99 true
    fmt.Println(syncMap.Load("WenFlower11")) // nil false
    
    // 删除 key 值
    syncMap.Delete("WenFlower")
    syncMap.Delete("WenFlower1111") // 删除不存在的 key 不会出现错误
    
    // 遍历
    syncMap.Range(func(key, value interface{}) bool {
        fmt.Printf("map[%s] = %d\n", key, value)
        return true
    })
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值