首页 > 其他分享 >Golang入门第三天

Golang入门第三天

时间:2023-02-05 03:46:15浏览次数:53  
标签:map 入门 int 第三天 Golang map1 func Printf type

  1. 获取命令行参数
  2. init函数
  3. 局部变量和全局变量
  4. 变量的内存和变量的地址
  5. 指针变量的使用
  6. new函数的使用
  7. 值传递
  8. 引用传递
  9. 随机数的使用
  10. 数组
  11. 切片
  12. map
  13. 结构体
  14. 可见性规则
package main

import (
	. "fmt"
	"math/rand"
	"os"
	"time"
)

// init函数,包被引用时,自动调用的函数,引用包优先当前包
func init() {
	println("main包的init函数")
}

// 获取命令行参数
func demo1() {
	list := os.Args
	for i := range list {
		Printf("list[%d] = %v\n", i, list[i])
	}
}

// 局部变量和全局变量
func demo2() {
	a := 1
	{
		a := 2
		println("内部 a = ", a)
	}
	println("外部 a = ", a)
}

// 变量的内存和变量的地址
func demo3() {
	// 内存1
	a := 1
	// 地址&a
	p := &a
	Printf("a = %v, p = %v\n", a, p)
}

// 指针变量的使用
// 不能操作没有合法指向的指针
func demo4(a *int) (result *int) {
	// 修改地址a中的值
	*a = 666
	result = a
	return
}

// new函数的使用
func demo5() {
	// p是*int
	p := new(int)
	Printf("这里是new函数的使用,p.type = %T, p = %v\n", p, p)
}

// 值传递
func demo6(a int) {
	println("这里是值传递,a = ", a)
}

// 引用传递
func demo7(p *int) {
	println("这里是引用传递,p = ", p)
}

// 随机数的使用
func demo8() {
	// 种子参数一样,生成随机数结果固定
	a := rand.Int()
	// 生成指定范围内的随机数
	b := rand.Intn(100)
	// 按时间生成随机数
	c := rand.Intn(int(time.Now().UnixNano()))
	Printf("生成的随机数为 a = %d,b = %d, c = %d", a, b, c)
}

// 数组和切片
func demo9() {
	// 全量初始化
	array := [5]int{1, 2, 3, 4, 5}
	// 部分初始化
	array1 := [5]int{1, 2}
	// 指定初始化
	array2 := [5]int{2: 2}
	// 二维数组
	array3 := [5][2]int{1: {2, 4}}
	Printf("这里是数组,array = %v,array1 = %v,array2 = %v, array3 = %v\n", array, array1, array2, array3)
	// 数组可以比较和赋值
	Printf("这里是数组赋值比较,array == array1 %v\n", array == array1)
	// 数组做函数参数是值拷贝
	func(arr [5]int) {
		Printf("这里是数组参数传递值拷贝,arr == array %v,&arr == &array %v\n", arr == array, &arr == &array)
	}(array)
	// 数组指针做函数参数
	func(p *[5]int) {
		Printf("这里是数组指针参数传递,p == &array %v, p = %v\n", p == &array, p)
	}(&array)
	// 冒泡排序
	array4 := func() (result [5]int) {
		for i := 0; i < 5; i++ {
			b := rand.Intn(100)
			result[i] = b
		}
		return
	}()
	array5 := func(arr [5]int) (result [5]int) {
		for i := 0; i < 5-1; i++ {
			for j := 0; j < 5-1-i; j++ {
				if arr[j] > arr[j+1] {
					arr[j], arr[j+1] = arr[j+1], arr[j]
				}
			}
		}
		return arr
	}(array4)
	Printf("这里是数组,array4 = %v,排序后,array5 = %v\n", array4, array5)
	// [...]int{} ...代表不确定长度,根据初始化元素数量推测长度
	array6 := [...]int{1}
	Printf("这里是数组,不定长数组array6 = %v,排序后,array6.type = %T\n", array6, array6)

	// 数组切片slice
	// 数组定义后就不可以更改长度,从而提供了数组切片,它通过内部指针和相关属性引用数组片段,以实现变长方案
	// 切片slice并不是真正的动态数组,而是一个引用类型,slice底层总是指向一个数组,声明也可以像数组一样,只是不需要长度
	// array[begin:end:cap],begin起始下标,end结束下标(不包含),cap容量=cap-begin,缺省为原数组长度
	array7 := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	slice := array7[0:4:5]
	// 缺省cap为原数组长度
	slice2 := array7[5:8]
	// 从第5开始,截取到末尾,容量为数组长度-5
	slice3 := array7[5:]
	// 从0开始,截取到8,容量也为8
	slice4 := array7[:8]
	// 切片的底层都是指向一个数组
	slice5 := slice4[:9]
	Printf("这里是切片,slicer = %v,slicer.type = %T,slicer2 = %v,slicer2.type = %T\n", slice, slice, slice2, slice2)
	Printf("这里是切片,slicer3 = %v,slicer3.type = %T,slicer4 = %v,slicer4.type = %T\n", slice3, slice3, slice4, slice4)
	Printf("这里是切片,slicer5 = %v,slicer5.type = %T\n", slice5, slice5)
	// append,在切片的末尾进行追加
	var slice6 []int = append(slice5, -1, -2, -3)
	Printf("这里是切片,slicer5追加后: slicer6 = %v,slicer6.type = %T\n", slice6, slice6)
	// 切片追加后,如果超出cap,那么将以两倍形式扩容
	// 切片做函数参数,是引用传递,不是值拷贝
	func(s1 []int) {
		oldCap := cap(s1)
		for i := 0; i < 10; i++ {
			if cap(s1) > oldCap {
				Printf("这里是切片,cap(s1) = %v,oldCap = %v\n", cap(s1), oldCap)
				oldCap = cap(s1)
			}
			s1 = append(s1, -1)
		}
	}(array7[:1:1])
}

// map(映射,字典)一个无序的K-V结构
func demo10() {
	// map中的K是唯一的,且必须支持==和!=操作的类型,切片/函数以及包含切片的结构类型,不可作为K,因为存在引用语义,会编译错误
	var map1 map[string]string
	// map 只有 len, 没有cap
	Printf("这里是map,map1 = %v, map1.type = %T, len(map) = %v\n", map1, map1, len(map1))
	// map通过make来进行初始化
	map1 = make(map[string]string)
	// 可指定长度,不足时可自动扩容,扩容机理类似append
	map1 = make(map[string]string, 1)
	map1["a"] = "map-a"
	map1["b"] = "map-b"
	Printf("这里是map,初始化后 map1 = %v, map1.type = %T, len(map) = %v\n", map1, map1, len(map1))
	// 重复赋值即为修改内容
	map1["a"] = "map-a-a"
	Printf("这里是map,修改内容 map1 = %v, map1.type = %T, len(map) = %v\n", map1, map1, len(map1))
	// 删除内容
	delete(map1, "a")
	Printf("这里是map,删除内容 map1 = %v, map1.type = %T, len(map) = %v\n", map1, map1, len(map1))
	// 遍历map
	for k, v := range map1 {
		Printf("这里是map,遍历内容 map1[%v] = %v\n", k, v)
	}
	// 判断元素是否存在map
	key := "a"
	value, result := map1[key]
	if result {
		Printf("这里是map,判断元素Key存在: result = %v, map1[%v] = %v\n", result, key, value)
	} else {
		Printf("这里是map,判断元素Key存在: result = %v\n", result)
	}
	// map做函数参数是引用传递
	func(m1 map[string]string) {
		m1["a"] = "m1-a"
		Printf("这里是map,map做函数参数为引用传递: m1 = %v, map1 = %v\n", m1, map1)
	}(map1)

}

// 结构体
func demo11() {
	// 结构体可被比较与赋值,具有值传递与引用传递
	type Student struct {
		Id   int
		Name string
		Age  int
		Sex  byte
	}
	// 顺序初始化
	var s1 = Student{1, "radish", 20, 'm'}
	Printf("这里是结构体,顺序初始化: s1 = %v, s1.type = %T\n", s1, s1)
	// 指定成员初始化,未初始化赋值为0
	s2 := Student{Id: 1, Name: "radish"}
	Printf("这里是结构体,指定成员初始化: s2 = %v, s2.type = %T\n", s2, s2)
	// 结构体的指针变量初始化
	var p1 *Student
	p1 = &Student{1, "radish", 20, 'm'}
	Printf("这里是结构体,结构体指针变量顺序初始化: p1 = %v, p1.type = %T\n", p1, p1)
	p2 := &Student{Name: "redish"}
	Printf("这里是结构体,结构体指针变量指定成员初始化: p2 = %v, p2.type = %T\n", p2, p2)
	// 操作成员
	s1.Id = 2
	s1.Name = "radish40"
	Printf("这里是结构体,操作成员: s1 = %v, s1.type = %T\n", s1, s1)
	// 通过指针操作成员
	// p1.Id和(*p1).id完全等价,只能使用.运算符
	p1 = new(Student)
	p1.Id = 2
	p1.Name = "radish40"
	Printf("这里是结构体,通过指针操作成员: p1 = %v, p1.type = %T\n", p1, p1)
}

func main() {
	var (
		a = 10
		p = &a
	)
	demo1()
	demo2()
	demo3()
	demo4(p)
	demo5()
	demo6(a)
	demo7(p)
	demo8()
	demo9()
	demo10()
	demo11()
}

标签:map,入门,int,第三天,Golang,map1,func,Printf,type
From: https://www.cnblogs.com/radish40/p/17092772.html

相关文章

  • 简易的git命令行入门教程
    一、Git全局设置gitconfig--globaluser.name"用户名"gitconfig--globaluser.email"邮件地址@163.com"二、创建git仓库mkdir项目名cd项目名gitinitt......
  • C++ Primer 5th 阅读笔记:入门指南
    学习方法Thewaytolearnanewprogramminglanguageistowriteprograms.学习一门新编程语言的方式是编写程序。函数(Function)函数的四部分:返回类型;函数......
  • vuejs从入门到精通——watch侦听器——侦听数据源类型
    watch侦听器——侦听数据源类型https://cn.vuejs.org/guide/essentials/watchers.html#basic-examplewatch的第一个参数可以是不同形式的“数据源”:它可以是一个ref(包......
  • vuejs从入门到精通——watch侦听器
    watch侦听器https://cn.vuejs.org/guide/essentials/watchers.html虽然计算属性在大多数情况下更适合,但有时也需要一个自定义的侦听器。 这就是为什么vue通过watch......
  • Docker入门
    Docker入门一、Docker为什么会出现此外,Docker是基于Go开发的。二、虚拟化技术和容器化技术的对比(1)虚拟化技术的缺点·资源占用十分多·冗余步骤多·启动很慢(2)容......
  • golang入门
    golang第一次学习数据类型序号类型和描述1布尔型布尔型的值只可以是常量true或者false。一个简单的例子:varbbool=true。2数字类型整型int和浮......
  • golang笔记
    手册网站:https://studygolang.com/pkgdocos.OpenFile("./app.log",os.O_CREATE|os.O_RDWR|os.O_APPEND,0644)app.log是文件名字,os.O_CREATE|os.O_RDWR|os.O_APPEND是......
  • vuejs从入门到精通——计算属性缓存 vs 方法
    计算属性缓存vs方法https://cn.vuejs.org/guide/essentials/computed.html#basic-exampletemplate:<p>{{calculateBooksMessage()}}</p>js://组件中fun......
  • vuejs从入门到精通——可写计算属性
    可写计算属性https://cn.vuejs.org/guide/essentials/computed.html#basic-example 计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。只在......
  • vuejs从入门到精通——计算属性
    计算属性https://cn.vuejs.org/guide/essentials/computed.html模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。......