映射map
在go中, map是固定类型的键值对的集合, 区别于js中的map
声明map
var mapList1 map[string]int // 声明
fmt.Println(mapList1) // map[]
fmt.Println(mapList1 == nil) // true
// mapList1["width"] = 100 // panic: assignment to entry in nil map 需要make以后才能使用
开辟内存空间并初始化
mapList2 := make(map[string]int, 2) // 使用全局make函数开辟内存空间
fmt.Println(mapList2) // map
fmt.Println(mapList2 == nil) // false
fmt.Println(len(mapList2)) // 0
mapList2["width"] = 100
mapList2["height"] = 100
mapList2["weight"] = 100
fmt.Println(len(mapList2)) // 3
fmt.Println(mapList2) // map[height:100 weight:100 width:100]
查key的value
value, ok := mapList2["weight"] // 取值
if ok {
fmt.Println("value: ", value) // value: 100
}
删除key
delete(mapList2, "weight") // 删除键
fmt.Println(mapList2) // map[height:100 width:100]
_, ok = mapList2["weight"]
if !ok {
fmt.Println("weight has been deleted") // weight has been deleted
fmt.Println("len(mapList2): ", len(mapList2)) // len(mapList2): 2
}
用map解决两数之和
func twoSum(nums []int, target int) []int {
var res []int
memory := make(map[int]int)
for index, value := range nums {
memory[value] = index
}
for index, value := range nums {
_index, ok := memory[target - value]
if ok && _index != index {
res = append(res, index, _index)
break
}
}
return res
}
结构体struct
在go中, 结构体是开发者自定义的新类型, 可以是不同类型的键值对的集合
类型定义与类型别名
type MyIntA int // 类型定义, 定义新类型
type MyIntB = int // 类型别名 alias, 没有定义新类型
var myIntA MyIntA
var myIntB MyIntB
fmt.Printf("%T \n", myIntA) // main.MyIntA
fmt.Printf("%T \n", myIntB) // int
定义结构体
// 结构体
type Pig struct {
name, color string // 相同类型的属性可以合并在同一行
age int
bool // 匿名属性
}
声明实例化
var p1 Pig // 声明结构体的实例
fmt.Printf("%T \n", p1) // main.Pig 类型
fmt.Println(p1) // { 0 false} 各属性默认零值
fmt.Printf("%#v \n", p1) // main.Pig{name:"", color:"", age:0, bool:false} 查看实例的详细信息
p1.name = "小猪佩奇"
p1.color = "pink"
p1.age = 7
p1.bool = false // 匿名属性赋值
fmt.Println(p1) // {Pappa Pig pink 7 false}
fmt.Printf("%v \n", p1) // {Pappa Pig pink 7 false}
fmt.Printf("%#v \n", p1) // main.Pig{name:"Pappa Pig", color:"pink", age:7, bool:false}
实例的内存分配
fmt.Printf("%p \n", &p1) // 0xc000078180 查看实例的内存地址
fmt.Printf("%p \n", &p1.name) // 0xc000078180 查看实例的name属性内存地址
fmt.Printf("%p \n", &p1.color) // 0xc000078190 查看实例的color属性内存地址
fmt.Printf("%p \n", &p1.age) // 0xc0000781a0 查看实例的age属性内存地址
fmt.Printf("%p \n", &p1.bool) // 0xc0000781a8 查看实例的bool属性的内存地址
new实例化
使用全局new函数实例化, 类似js中的new关键字
p2 := new(Pig)
fmt.Printf("%T \n", p2) // *main.Pig main包里的Pig类型的指针
fmt.Printf("%p \n", p2) // 0xc0000782d0 查看指针的内存地址
fmt.Printf("%p \n", &p2) // 0xc00000e030 查看指针指向的实例的内存地址
p2.name = "George" // 可以通过指针直接给实例赋值
p2.color = "pink"
p2.age = 5
p2.bool = true
取结构体地址实例化
p3 := &Pig{}
fmt.Printf("%T \n", p3) // *main.Pig main包里的Pig类型的指针
属性赋值实例化
// 使用键值对实例化的同时初始化
p4 := Pig{
name: "p4", // 注意属性后面的逗号
age: 5,
bool: false, // 匿名属性初始化
}
fmt.Printf("%T \n", p4) // main.Pig 类型
fmt.Printf("%#v \n", p4) // main.Pig{name:"p4", color:"", age:5, bool:false} 没初始化的属性为零值
结构体取地址并初始化
// 使用值实例化的同时初始化并取地址, 按顺序挨个给属性初始化
p5 := &Pig{
"p5",
"pink",
5,
true, // 注意最后一个属性的后面也要有逗号
}
fmt.Printf("%T \n", p5) // *main.Pig
fmt.Printf("%#v \n", p5) // &main.Pig{name:"p5", color:"pink", age:5, bool:true}
空结构体
p6 := Pig{}
fmt.Printf("%T \n", p6) // main.Pig
fmt.Printf("%#v \n", p6) // main.Pig{name:"", color:"", age:0, bool:false}
构造函数
func newPig(name, color string, age int, gender bool) *Pig {
return &Pig{
name: name,
color: color,
age: age,
bool: gender,
}
}
// 使用构造函数生成实例
p7 := newPig("p7", "pink", 7, true)
fmt.Printf("%T \n", p7) // *main.Pig
fmt.Printf("%#v \n", p7) // &main.Pig{name:"p7", color:"pink", age:7, bool:true}
添加实例方法
// 添加方法, 形参为Pig首字母小写p, 类似js中的this, 指向当前实例
func (p Pig) say(hobby string) (mood string, isSmile bool) {
fmt.Printf("我是%s, 我喜欢%s儿~ \n", p.name, hobby)
return "happy", true
}
// 调用方法
mood, isSmile := p1.say("踩泥坑") // 我是小猪佩奇, 我喜欢踩泥坑儿~
fmt.Printf("mood: %s, isSmile: %v \n", mood, isSmile) // mood: happy, isSmile: true
值类型接收者和指针类型接收者
// 值类型接收者
func (p Pig) growUpValue(year int) {
p.age += year
}
// 指针类型接收者
func (p *Pig) growUpPointer(year int) {
p.age += year
}
fmt.Printf("age: %v \n", p1.age) // 7
p1.growUpValue(1)
fmt.Printf("age: %v \n", p1.age) // 7 只改变了值副本的age属性值
p1.growUpPointer(1)
fmt.Printf("age: %v \n", p1.age) // 8 改变了引用的age属性值
嵌套结构体与继承
// 嵌套结构体
type PigWithSister struct {
name string
sister Pig
*Pig // 匿名属性嵌套结构体指针
}
p8 := PigWithSister{
name: "乔治",
sister: p1,
Pig: &Pig{
name: "乔治",
},
}
fmt.Printf("%s的姐姐是%s\n", p8.name, p8.sister.name) // 乔治的姐姐是小猪佩奇~
p8.say("踩泥坑") // 我是乔治, 我喜欢跳泥坑儿~ 继承了Pig的say方法
tag、序列化与反序列化
type Dog struct {
Kind string `json:"kind"`
name string // 属性名首字母小写, 为本包私有, 不能被json包访问
Smart bool
}
// 序列化与反序列化
d1 := Dog{
name: "wangwang",
Kind: "husky",
Smart: true,
}
dataStr, err := json.Marshal(d1)
if (err == nil) {
fmt.Printf("dataStr: %s \n", dataStr) // dataStr: {"kind":"husky","Smart":true}
dataObj := &Dog{}
err := json.Unmarshal([]byte(dataStr), dataObj)
if (err == nil) {
fmt.Printf("dataObj: %#v \n", dataObj) // dataObj: &main.Dog{Kind:"husky", name:"", Smart:true} name属性为零值
}
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!