【golang学习笔记2.2】 Map、结构体和接口

Map的基本介绍

map是一个key-value的数据结构;类似于其他编程语言中的集合
基本语法和注意事项

  1. var map 变量名 map[keytype]valuetype
  2. keytype的类型有很多种比如bool,string,指针 ,管道,接口,结构体,数组等
  3. keytype通常为int,string,slice,map,function不可以,因为这几个没法用==来进行判断
  4. valuetype的类型和keytype差不多。通常为数字类型【int ,float】,stiring,结构体
  5. map的声明不会分配内存,初始化需要make,分配内存后才可以赋值使用

map的声明和简单使用

package main

import (
	"fmt"
)
func main() {
	//第一种 先声明 在初始化
	var mapp map[string]string
	//这样赋值会报错,因为没有给分配内存空间
	//mapp["n1"]="张三“
	mapp = make(map[string]string)
	mapp["n1"] = "张三"
	mapp["n2"] = "李四"
	mapp["n3"] = "王武"
	mapp["n1"] = "开心"
	mapp["n4"] = "乐哈哈"
	//打印结果 mapp: map[n1:开心 n2:李四 n3:王武 n4:乐哈哈]
	fmt.Printf("mapp: %v\n", mapp)
	//第二种 直接进行初始化
	var mapas = make(map[string]string)
	mapas["n1"] = "张三"
	fmt.Printf("mapas: %v\n", mapas)
	//第三种 直接赋值
	var maps = map[int]string{
		0: "张三",
		1: "李四",
		2: "王武",
	}
	fmt.Printf("maps: %v\n", maps)
}

map的增删改查

package main
import (
	"fmt"
)
func main() { 
	var mapas = make(map[string]string)
	//没有就是增加,存在就是修改
	mapas["n1"] = "张三"
	mapas["n2"] = "李四"
	mapas["n3"] = "王五"
	mapas["n1"] = "赵六"
	fmt.Printf("mapas: %v\n", mapas)
	//单个删除 delect 内置函数,删除map里面的指定key【键名】,如果存在就删除,不存在也不执行,不会报错
	delete(mapas,"n1")
	//批量删除【清空map】;重新进行初始化,原来的会被go的垃圾回收机制回收
	mapas=make(map[string]string)
	fmt.Printf("mapas: %v\n", mapas)
	//查找指定的mapkey;会返回值和一个bool;为true时存在为fasle不存在
	val,boola:=mapas["n2"]
	if boola{
		fmt.Printf("val: %v\n", val)
	}else{
		 fmt.Printf("err: %v\n", boola)
	}
}

map的遍历

map只能使用for-range循环

package main

import (
	"fmt"
)

func main() {

	var mapas = make(map[string]string)
	mapas["n1"] = "张三"
	mapas["n2"] = "李四"
	mapas["n3"] = "王五"
	mapas["n4"] = "赵六"
	for k, v := range mapas {
		fmt.Printf("k: %v v: %v\n", k, v)
	}
}

map切片【动态添加切片】

package main

import (
	"fmt"
)

func main() {
	//map第一种 先声明分配一些内存
	var mapas= make([]map[string]string,2)
	   //声明固定内存
	   mapas[0]=make(map[string]string,2)
	   mapas[0]["age"]="20"
	   mapas[0]["name"]="张三"
	   //默认分配
	   mapas[1]=make(map[string]string)
	   mapas[1]["age"]="30"
	   mapas[1]["name"]="李四"

	   newName:=map[string]string{
		  "age":"40",
		  "name":"王五",
	   }
	   //在使用append()方法进行动态添加
	   mapas=append(mapas, newName)
	   fmt.Printf("mapas: %v\n", mapas) 
	 //第二种  声明一个map切片;然后直接使用append方法追加
	 var mapas2 []map[string]string
	   newName2:=map[string]string{
		  "age":"40",
		  "name":"王五",
	   }
	   //在使用append()方法进行动态添加
	   mapas2=append(mapas2, newName2)
	   fmt.Printf("mapas2: %v\n", mapas2) 
}

map使用的细节

  1. map是引用类型,遵守引用类型传递的机制,在一个函数接受map,会修改原来的map
  2. map的容量到达到后,map会自动扩容,也就是说map是动态增长的key-value键值对
package main

import (
	"fmt"
)

func num(map1 map[int]int){
	     map1[2]=10000
}

func main() {
    map1:=make(map[int]int)
	map1[10]=10
	map1[2]=20
	map1[4]=1110
	map1[7]=130
	map1[8]=145
	map1[1]=121
	num(map1)
	//打印结果 map1: map[1:121 2:10000 4:1110 7:130 8:145 10:10]
	//这里的map[2]就被函数直接修改了,所以说明map是引用类型 
	fmt.Printf("map1: %v\n", map1)
}

结构体

结构体是自定义的数据类型,代表一类事物。
结构体变量是具体的,代表一个具体的变量。
我这里理解的是把结构体当作php中的类来看 好容易理解一些
案例1:

package main

import (
	"fmt"
)

//声明一个结构体
type Person struct {
	//Name 可以理解为字段
	//string 可以理解为这个字段的属性
	// `json:"skin"` tag 返回数据格式和名称
	Name   string  `json:"name"`
	Age    int
	Scores [2]float64
	Ptr    *int
	Slice  []int
	map1   map[int]int
	boola  bool
}

func main() {

	var person Person
	//如果没有给结构体默认值,那么结构体会返回对应类型的初始值
	//并且有些是没有分配内存是无法直接使用的,比如结构体 如果不先make那么无法直接对其进行赋值
	//打印结果 person: { 0 [0 0] <nil> [] map[] false}
	fmt.Printf("person: %v\n", person)

}

案例2:

package main

import (
	"fmt"
)
//声明一个结构体
type test struct {
	name string 
	age  int 
	fenshu int 
}
func main() {
	//声明一个结构体,并初始化;注意name不需要加""
	 var test2 =test{
		 name:"张三",
		 age:20,
		 fenshu:100,
	}
	fmt.Printf("test2.name: %v\n", test2.name)
	fmt.Printf("test2.age: %v\n", test2.age)
	fmt.Printf("test2.fenshu: %v\n", test2.fenshu)
}

  1. 结构体的创建的几种方式
package main

import (
	"fmt"
)

//声明一个结构体
type Person struct {
	//Name 可以理解为字段
	//string 可以理解为这个字段的属性
	// `json:"skin"` tag 返回数据格式和名称
	Name   string  `json:"name"`
	Age    int
	Scores [2]float64
	Ptr    *int
	Slice  []int
	map1   map[int]int
	boola  bool
}

func main() {
    
	//第一种 
	var p1 Person
	//打印结果 person: { 0 [0 0] <nil> [] map[] false}
	fmt.Printf("p1: %v\n", p1)
    //第二种
	p2:=Person{}
	p2.Name="张三"
	//打印结果 p2: {张三 0 [0 0] <nil> [] map[] false}  
	fmt.Printf("p2: %v\n", p2)
	//第三种;new 会生成一个指针
	p3:=new (Person)
	p3.Name="李四"
	p3.Age=20
	//打印结果 p3: &{李四 20 [0 0] <nil> [] map[] false}
	fmt.Printf("p3: %v\n", p3)
	//第四种也会生成一个指针类型
	var p4 *Person=&Person{}
	p4.Name="王五"
	//打印结果 p4: &{王五 0 [0 0] <nil> [] map[] false}
	fmt.Printf("p4: %v\n", p4)
}
 

方法的声明(定义)

基本结构
func(名称 类型)方法名(参数列表【参数 类型,参数 类型…】)(返回值列表【返回值 类型,返回值 类型…】){
代码…
//return和返回值列表不是一定需要的;
return 返回值
}
案例1:

package main

import (
	"fmt"
)

//声明一个结构体
type Person struct {
	Name   string  `json:"name"`
	Age    int
	Scores [2]float64
	Ptr    *int
	Slice  []int
	map1   map[int]int
	boola  bool
}
//给Person绑定一个方法
func(p Person) test(){
    p.Name="张三"
	fmt.Printf("p: %v\n", p)
}
func(p *Person)test2(){
	 p.Name="赵六"
	 fmt.Printf("p: %v\n", p) 
} 
func main() {
	//第一种 
	var p1 Person
	p1.Name="李四"
	//调用方法
	//打印结果 p: {张三 0 [0 0] <nil> [] map[] false} 
    p1.test()
	//打印结果 p1: {李四 0 [0 0] <nil> [] map[] false}
	fmt.Printf("p1: %v\n", p1)
    //总结
	//调用方法并不会改变方法外的值。
	//这种方法为值传递;是值拷贝的传递方式。不是引用类型
	//如果想调用方法改变外面的值;那么方法里面使用指针类型即可
	p2:=new (Person)
	p2.Name="张三"
	//打印结果 p: &{赵六 0 [0 0] <nil> [] map[] false} 
	p2.test2()
	//打印结果 p2: &{赵六 0 [0 0] <nil> [] map[] false}
	fmt.Printf("p2: %v\n", p2)
}

案例2:

package main

import (
	"fmt"
)

//声明一个结构体
type Person struct {
	Name   string  `json:"name"`
	Age    int
	Scores [2]float64
	Ptr    *int
	Slice  []int
	map1   map[int]int
	boola  bool
}
//给Person绑定一个方法
func(p Person) test(num int)int{
    p.Name="张三"
	fmt.Printf("p: %v\n", p)
	num=num+1 
	return num
}
 
func main() {
	 
	var p1 Person
	num:=p1.test(2)
    fmt.Printf("num: %v\n", num)
}

接口的定义

接口类型可以定义一组方法,不需要实现,接口里面不能包含任意变量,在定义结构体的时候 在具体实现方法

package main

import (
	"fmt"
)
//定义一个接口,接口里面有一个跳转不同页面的方法
type Home interface {
	HomeIndex()
}
//定义新闻首页的结构体
type NewList struct {
}

//定义调用新闻首页的方法
func (new NewList) HomeIndex() {
	fmt.Printf("新闻首页")
}
//定义一个新闻首页独有的方法
func (new NewList)Banner(){
    fmt.Printf("新闻轮播图")
}
//定义店铺首页的结构体
type ShopHome struct {
}

//定义调用店铺首页的方法
func (shop ShopHome) HomeIndex() {
	fmt.Printf("店铺首页")
}

//声明一个进入的初始化结构体
type Index struct {
}

//定义一个引用接口为参数的方法;里面是调用接口里面的方法
func (index Index) Index(home Home) {
	home.HomeIndex()
	//类型断言;判断是否调用不同的结构体方法
	if NewList,ok:=home.(NewList);ok{
         NewList.Banner()  
	}
}

func main() {
	//创建结构体
	new := NewList{}
	shop := ShopHome{}
	index := Index{}
	//调用方法;方法里面是引用的接口
	//打印结果是 新闻首页
	index.Index(new)
	fmt.Println()
	//打印结果是 店铺首页
	index.Index(shop)
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是 golang 学习笔记,希望对你有帮助: ### 1. 基本语法 - 包声明:每个 Go 程序都是由多个包组成,使用 `package` 声明包名。 - 引入包:使用 `import` 关键字引入需要的包。 - 函数:使用 `func` 关键字声明函数,函数可以有多个返回值。 - 变量:使用 `var` 关键字声明变量。 - 常量:使用 `const` 关键字声明常量。 - 控制语句:Go 语言支持条件语句和循环语句,例如 `if`、`switch`、`for` 等。 ### 2. 数据类型 Go 语言支持以下数据类型: - 布尔型:`bool` - 数字类型:`int`、`int8`、`int16`、`int32`、`int64`、`uint`、`uint8`、`uint16`、`uint32`、`uint64`、`uintptr`、`float32`、`float64`、`complex64`、`complex128` - 字符串类型:`string` - 派生类型:`array`、`slice`、`map`、`struct`、`interface`、`channel` ### 3. 函数 Go 语言中的函数可以有多个返回值,可以使用命名返回值来使函数更加清晰易读。例如: ```go func swap(x, y string) (string, string) { return y, x } ``` ### 4. 数组和切片 Go 语言中的数组和切片都是支持多维的。数组和切片的区别在于数组长度是固定的,而切片长度可以动态变化。例如: ```go // 声明数组 var a [5]int // 声明切片 var s []int s = append(s, 1, 2, 3) ``` ### 5. 结构体 结构体是一种自定义的数据类型,可以包含多个不同类型的字段。例如: ```go type person struct { name string age int } func main() { p := person{"Bob", 20} fmt.Println(p.name, p.age) } ``` ### 6. 接口 接口定义了一组方法的集合,只要某个类型实现了接口中定义的所有方法,就可以认为它实现了这个接口。例如: ```go type Shape interface { area() float64 } type Circle struct { x, y, r float64 } func (c Circle) area() float64 { return math.Pi * c.r * c.r } func main() { var s Shape s = Circle{x: 0, y: 0, r: 5} fmt.Println(s.area()) } ``` ### 7. 并发 Go 语言使用协程来实现并发,协程是一种轻量级的线程,可以在一个线程中同时执行多个协程。例如: ```go func main() { go say("world") say("hello") } func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } ``` 以上就是 golang 学习笔记的主要内容,希望对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是誰萆微了承諾

你的鼓励是对我最大的支持

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

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

打赏作者

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

抵扣说明:

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

余额充值