Go基本数据类型及内置函数(一文稳定基础)

本文介绍了Go语言的基础数据类型,包括布尔、字符串、整数、浮点数、复数、指针等,并详细讲解了内置函数如len、cap、make等的用法。此外,还讨论了函数、列表操作、原子性操作、通道、协程以及如何确保并发安全。最后,文章提到了定时器的使用,展示了如何创建和管理定时任务。
摘要由CSDN通过智能技术生成

1. 基础数据类型

	1. bool:布尔类型,只有 truefalse 两个值。
		var test2 bool = true
		
	2. string:字符串类型,表示一组字符序列。
		var test2 string = "GO从入门到入坑"
		
	3. intint8int16int32int64:整数类型,分别表示有符号整数类型的不同大小(表示可以为负数)var test3 int = -666
		
	4. uintuint8uint16uint32uint64:无符号整数类型,分别表示无符号整数类型的不同大小(表示不能为负数)。
		var test4 uint = 777
		
	5. uintptr:无符号整数类型,用于存储指针。
		var x int = 10
		var p uintptr = uintptr(unsafe.Pointer(&x))
		fmt.Printf("x = %d, p = %d\n", x, p)
		// 	这句话是将一个普通的变量 x 的指针地址转换为 uintptr 类型的无符号整数,然后再将其转换为 unsafe.Pointer 类型的指针。这个过程通常被称为指针的类型转换或强制类型转换。
		
	6. float32float64:浮点数类型,分别表示单精度和双精度浮点数。
		var test5 float32 = 3.14
		
	7. complex64complex128:复数类型,分别表示具有 float32float64 组件的复数值。
		// complex 函数是Go语言中的一个内置函数,用于创建一个复数值。它接受两个参数,分别表示复数的实部和虚部,返回一个 complex128 类型的复数值。
		var realpart float32 = 1.24
	    var imagpart float32 = 2.34
	    var c complex64 = complex(realpart, imagpart)
		// 输出 (1.24+2.34i) 
	    // (1.24+2.34i) 表示一个复数值,其中实部为 1.24,虚部为 2.34i。在复数中,i 表示虚数单位,即 i²=-1。因此,2.34i 表示一个虚部为 2.34 的复数。
	    
	8. 字符型(runebytevar test6 rune = 'A'
		// 输出  65  在ASCII码中,字符 'A' 的代码点是十进制数 65
		
	8.map字典
		m := map[string]int{"foo": 1, "bar": 2, "baz": 3}
		
	9.Pointer指针
		//	指针用于存储变量的内存地址。指针类型在 Go 语言中是一种基本数据类型,它允许程序直接访问和修改变量的内存地址,从而可以实现对变量的间接操作。
		x := 10
		p := &x // 获取 x 的地址
	
		fmt.Println(x, p)
		fmt.Println(*p) // 输出 10,*p 表示访问指针 p 所指向的变量的值
	
		*p = 20        // 修改指针 p 所指向的变量的值为 20,即修改变量 x 的值为 20
		fmt.Println(x) // 输出 20

2.内置函数

	1.len:返回传入参数的长度,如字符串、数组、切片、字典或通道等。
		l := []int{1, 2, 3, 4, 5, 6}
		fmt.Println(len(l))		// 输出 6
	
	2.cap:返回传入参数的容量,如切片或数组等。
		l := []int{1, 2, 3, 4, 5, 6}
		fmt.Println(cap(l))		// 输出 6 
	
	2.make:用于创建动态类型的值,如切片、映射、通道等。
	    //创建切片
	        m := make([]int, 3, 5)	// 一个长度为 3、容量为 5 的整型切片,并初始化所有元素为 0,当切片的长度超过其容量时,切片会自动扩容
	        fmt.Println(m)		   // 输出 [0 0 0]
	
		//创建映射
			m := make(map[T1]T2, capacity)	//T1表示映射的键类型,T2表示映射的值类型,capacity表示映射的容量。									    capacity是可选参数,如果省略,则默认为0。
			m := make(map[string]int, 10)	// 创建一个容量为10的字符串到整型的映射
		// 创建通道
			ch := make(chan T, capacity)	// T表示通道中元素的类型,capacity表示通道的容量。capacity是可选											参数,如果省略,则默认为0。
			ch := make(chan string, 10)		//创建一个容量为10的字符串通道
	
	3.append:用于将元素追加到切片中。
		qq := []int{1, 7, 1, 1, 0, 3}
		qq = append(qq, 1, 0, 0, 6)
		fmt.Println(qq)		  // 追加尾部 [1 7 1 1 0 3 1 0 0 6]
	
	4.copy:用于将一个切片的内容复制到另一个切片中。
		qq := []int{1, 7, 1, 1, 0, 3}
		ql := []int{1, 0, 0, 6}
		ll := copy(qq, ql)
		fmt.Println(ll) // 输出 4
		fmt.Println(qq)	// 输出 [1 0 0 6 0 3]  如果ql是空则完全赋值qq 如果ql不是空则保留ql已有的加上qq对应的后续(ql四位数保留 复制qq第五位开始)
	
	5.close:用于关闭通道。
		ch := make(chan int)
		go func() {
			for i := 0; i < 5; i++ {
				ch <- i // 使用通道操作符 <- 向通道 ch 发送一个整数值 i
			}
			close(ch) // 关闭通道
		}()
		for n := range ch { // 循环ch 赋值n打印
			fmt.Println(n)
		}
	
	6.panicrecover:用于处理程序中的异常情况。引发一个运行时恐慌,v 可以是任何值。	
	    func main(){	
	        fmt.Println("start")		// 1
	        doSomething()				// 2
	        fmt.Println("end")
	    }
	    func doSomething() {
	        fmt.Println("Doing something")	// 3
	        panic("Error!")				// 4 结束当前程序 不继续向下运行调出栈信息
	    }
		// 输出   start
	    //        Doing something
	    //        panic: Error!
	
	    //        goroutine 1 [running]:
	    //        main.doSomething(...)
	    //                D:/one/基础数据类型.go:122
	    //        main.main()
	    //                D:/one/基础数据类型.go:116 +0xa8
	
		// 程序在执行 doSomething 函数时发生了 panic,并输出了一个字符串 "Error!"。在这种情况下,程序会立即退出,并打印出调用栈信息,以便开发人员进行调试和排查问题。
	
	7.printprintln、printf:用于将给定的参数打印到控制台。
		a := "hello"
	    b := 123
	    fmt.Print(a, b) // 输出:hello123 Print函数用于将指定的参数打印到标准输出中,不会自动换行。
	
		a := "hello"
	    b := 123
	    fmt.Println(a, b) // 输出:hello 123\n Println函数用于将指定的参数打印到标准输出中,会自动换行。
	
		a := "hello"
	    b := 123
	    fmt.Printf("%s %d", a, b) // 输出:hello 123	printf用于fmt字符串 %s字符串 %d数字
	
	8.new:返回一个类型为 T 的指针,指向一个新分配的零值,并返回其地址。
	    p := new(int) // 创建一个int类型的零值对象,并返回其地址
	    fmt.Println(*p) // 输出:0
	
	    *p = 123 // 通过指针修改对象的值
	    fmt.Println(*p) // 输出:123
	
	9.delete(m, key):从映射 m 中删除键值为 key 的元素。
		m := map[string]int{"a": 1, "b": 2, "c": 3}
	    delete(m, "b") // 删除键为"b"的键值对
	    fmt.Println(m) // 输出:map[a:1 c:3]

3.函数

	1. 无参函数
		func function1() {
			fmt.Println("无参函数 直接调用")
	    }	
		// 调用 function1()
	
		func function2() int {
			return 666 // 返回一个指定类型参数
	    }
		// 	res := function3()
		//  fmt.Println(res)
		//  or 
		//  fmt.Println(function3())
		
	2. 有参函数
		func function3(a, b int, c string) {
			fmt.Println("有参函数 指定类型依次传入")
	    }
		// function2(1, 2, "真6")
	
		func function4(a, b int) (int, int) {
			return a + b, b * a // 返回两个参数
		}
		// fmt.Println(function4(22, 33))
	
	3. 递归调用
		func function5() {
	        fmt.Println("6666")
	        function5() // 递归调用 函数调用自己本身
	    }
		// function5()
	
	4. 定义函数属性类型
		type Books struct {
	        title  string // 定义函数属性类型
	        author string
	    }
		//	var onebook Books
		//	onebook.title = "Go 好扯淡" // 函数 .操作属性
		//	onebook.author = "Mr.Mei"
		//	fmt.Println(onebook.title, onebook.author)
		//	fmt.Println(len(onebook.author))
	
	5. 占位符
		func GetData() (int, string) {
	        return 10, "hello"
	    }
		//	a, _ := GetData() 
		//  _, b := GetData()
		//  fmt.Println(a, b)

4.列表操作及for循环

	list := []int{123, 456, 789, 111}  // 定义列表
	list = append([]int{555}, list...) // 头部追加 ... == copy
	list = append(list, 222)           // 列表尾部追加 append
	fmt.Println(list)
	
	for i, v := range list { // for循环 i所引 v value
	    fmt.Println(i, v)
	}

5.原子性操作

	package main
	
	import (
		"fmt"
		"sync/atomic"
		"time"
	)
	
	func main() {
		var cnt uint32 = 0
		// 运行10次
		for i := 0; i < 10; i++ {
			// 执行匿名函数
			go func() {
				// 从10循环到199 每次sleep一毫秒时间 去原子操作 cnt
				for i := 10; i < 200; i++ {
					time.Sleep(time.Millisecond)
					atomic.AddUint32(&cnt, 1)
				}
			}()
		}
		time.Sleep(time.Second)
		// 原子读取 赋值
		cntFinal := atomic.LoadUint32(&cnt)
		fmt.Println("cnt:", cntFinal)
	}

6.通道

	package main
	
	import "fmt"
	
	func hello(done chan bool) {
		fmt.Println("Hello Goroutine")
		done <- true
	}
	
	func main() {
		done := make(chan bool)
		go hello(done)
		<-done
		fmt.Println("main function")
	}

7.协程与并发安全

	package main
	
	import (
		"fmt"
		"math/rand"
		"runtime"
		"sync"
		_ "sync"
		"time"
	)
	
	var total int32 = 10
	var mutex sync.Mutex
	var wg sync.WaitGroup
	
	//	func sell(i int) {
	//		for {
	//			if total > 0 {
	//				// 模拟延迟
	//				time.Sleep(time.Duration(rand.Intn(5)) * time.Millisecond)
	//				total--
	//				fmt.Println("id:", i, "  ticket:", total)
	//			} else {
	//				break
	//			}
	//		}
	//	}
	
	func sell(i int) {
		for total > 0 {
			mutex.Lock()
			if total > 0 {
				time.Sleep(time.Duration(rand.Intn(5)) * time.Millisecond)
				total--
				fmt.Println("id:", i, "  ticket:", total)
			}
			mutex.Unlock()
		}
		wg.Done()
	}
	
	func main() {
		// 设置CPU核心数 影响并发性能
		runtime.GOMAXPROCS(8)
		// 设置随机数种子 免随机生成的数字一样 当前使用时间戳
		rand.Seed(time.Now().Unix())
		wg.Add(5)
		// 使用for循环 如果i<5 i++ 当前i=0
		for i := 0; i < 5; i++ {
			go sell(i)
		}
		// 等待线程结束 查看当前票数
		wg.Wait()
		fmt.Println(total, "Done")
	}

8.定时器

	package main
	
	import (
		"fmt"
		"time"
	)
	
	func main() {
		ticker := time.NewTicker(time.Second) // 每隔1秒向其通道发送一个时间事件
	
		go func() {
			for t := range ticker.C {
				fmt.Println(t) // 使用for循环打印ticker.c通道的时间事件
			}
		}()
	
		timer := time.NewTimer(10 * time.Second) // 创建一个10秒的定时器,并将其赋值给变量timer
		<-timer.C                                // timer.C通道中接收一个时间事件 该操作会阻塞当前goroutine,直到定时器到期并发送时间事件.
		ticker.Stop()                            // 停止ticker定期发送时间事件。并输出一条信息表示定时器已经到期。 ticker.C通道已经关闭退出循环
		fmt.Println("timer expired!")
	}
	
	/*
	该代码实现了每秒钟打印一个时间戳,并在10秒钟后停止。在该代码运行期间,程序会一直处于运行状态,直到定时器到期并停止Ticker。该代码使用了goroutine和channel,可以保证每秒钟打印时间戳的同时,可以在10秒钟后及时停止Ticker,并且不会阻塞主线程。
	*/
	
	
	//2023-07-20 16:24:54.7060075 +0800 CST m=+5.008210801
	//2023-07-20 16:24:55.7068004 +0800 CST m=+6.009003701
	//2023-07-20 16:24:56.7066918 +0800 CST m=+7.008895101
	//2023-07-20 16:24:57.7022063 +0800 CST m=+8.004409601
	//2023-07-20 16:24:58.7061753 +0800 CST m=+9.008378601
	//timer expired!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoisMay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值