go_3 map/面向对象
1. map
slice map function 不可以做key 因为没法==比较
map是无序的
map是引用传递
var a map[string]string var b map[string]map[string]string key是string 值是map<string,string>
创建map的三种方式
1. var a map[string]string a = make(map[string]string,10) 需要make才能分配内存 a["n1"] = "rudy"
2. var map1 = make(map[string]string,10)
map1["a"]="1"
3. var map2 = map[string]string{
"hero1":"adsf",
"hero2":"123",
}
删除map中第值
delete(map2,"hero1")
查找map
v,res := map2["hero1"]
遍历map
for k, v := range map2 {
fmt.Println(k,v)
}
map的元素数量
len()
对map的key进行排序 先将key放入slice sort后再根据key取出value
m := map[int]string{ 1:"1",2:"2",3:"3", } var keys []int for k, _ := range m { keys = append(keys, k) } sort.Ints(keys) for _, key := range keys { v := m[key] fmt.Println(key,v) }
2. 面向对象struct
结构体是值类型 方法传递的时候不会修改值
type Cat struct { name string age int gander bool slice []int mymap map[string]string }
切片和map在使用之前需要make分配内存才能使用
创建结构体的四种方式
1. var cat Cat 2. c := Cat{ name: "asdf", } 3. c2 := new(Cat) (*c2).name = "1234" new 创建的是个指针 go简化了指针的写法可以实例直接赋值 * 是取值符 4. c3 := &Cat{name:"123"} & 创建的也是指针
字段在内存中是连续的
字段的名称 个数 类型一致才能强转
结构体进行type重新定义类型 go会认为是两个不同的数据类型 需要强转
tag `json:""` 序列化的时候可以修改别名
3. 方法
方法和结构体关联
方法也是值拷贝 在方法中的修改 不会影响到主方法
type A struct { Num int } func (a A) test() { fmt.Println("test()",a.Num) }
func NewStu(name string) *student { return &student{Name: name} } 当对象是私有的可以使用工厂模式创建实例
4. 继承
在结构体中引用匿名结构体就实现了
当继承中有相同当属性或方法 采用就近原则进行调用 想要调用继承当方法/属性 需要使用继承.结构体
type Book struct { *Student Title string } var b2 = model.Book{&model.Student{"asdf", 123}, "123"}
5. 接口
引用类型
一个结构体实现了接口的所有方法 就能使用多态
接口可以指向一个实现了该接口的自定义类型变量
接口如果继承了其他接口 实现类要实现所有的接口方法,但是接口之间的继承不能有相同的方法
6. 类型断言
var x interface{} var b float64 = 3.1 x = b b = x.(float64)
进行类型断言时类型不匹配就会报错
7. file
读取
带缓冲区带文件读取
file, err := os.Open("/Users/didi/goProjects/src/awesomeProject/test.txt") defer file.Close() if err != nil { fmt.Println("readfile error", err.Error()) } reader := bufio.NewReader(file) for { str,err := reader.ReadString('\n') if err == io.EOF { break } fmt.Print(str) } fmt.Println("read file over")
一次性读取文件到内存中 没有缓冲区
file, err := ioutil.ReadFile("/Users/didi/goProjects/src/awesomeProject/test.txt") if err != nil { fmt.Println("read file err",err.Error()) } fmt.Printf("%v",file)
写入
filePath := "/Users/didi/goProjects/src/awesomeProject/test2.txt" file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { fmt.Println("create file error") } defer file.Close() writer := bufio.NewWriter(file) writer.WriteString("rnm 退钱\n") writer.WriteString("你对得起我们吗?\n") writer.Flush() // 这个必须不能少 否则无法写入文件中
// 先清空再写入
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_TRUNC, 0666)
// 追加方式写入
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND, 0666)
// 可读可写方式
file, err := os.OpenFile(filePath, os.O_RDWR|os.O_APPEND, 0666)
判断文件是否存在
_, err := os.Stat(filePath) exist := os.IsNotExist(err) fmt.Println(exist)
8. 命令行参数
获取命令行参数
args := os.Args
var pass string var port int flag.StringVar(&pass,"pass","","pass") flag.IntVar(&port,"port",8080,"port") flag.Parse() // 这个方法必须得调用否则无法获取 fmt.Printf("pass is :%v,port is : %v",pass,port)
9. json
student := model.Student{ Name: "rudy", Age: 12, } marshal, _ := json.Marshal(student) fmt.Println(marshal) s := model.Student{} json.Unmarshal(marshal, &s) // 反序列化需要传递指针才能修改结构体的值
marshal := "{\"name\":\"rudy\",\"age\":12}\n" var a map[string]interface{} // 不需要make unmarshal方法会make json.Unmarshal([]byte(marshal), &a) fmt.Println(a)
10. 单元测试
go会把xxx_test.go结尾的文件,中的Testxxx开头的函数都调用一遍
文件名为sum_test.go //注意 单元测试go文件要以_test.go结尾
函数名以Test开头
函数名Test后面不能跟a-z
func Test_sum(t *testing.T) { i := sum(1) if i != 2 { t.Fatalf("执行错误,期望值是%v,实际值是:%v",2,3) } t.Log("执行成功") }
go test -v sum_test.go sum.go //测试指定文件中的所有测试用例
go test -v -test.run 函数名 // 测试单个方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!