golang学习笔记----struct 方法
结构方法:
方法根据传入的参数的不同,又分为:值传递 和 指针传递。两者的效果就是:值传递不可改变值,指针传递可以改变值。
- 值传递的适用于取值
- 指针传递适用于更改字段的值
type Response struct { Code int Result []byte Headers map[string]string } func (r Response) GetAttrCode() int { return r.Code } func (r Response) GetAttrResult() []byte { return r.Result } func (r Response) GetAttrHeader() map[string]string { return r.Headers } func (r *Response) SetCode(code int) { r.Code = code } func (r *Response) SetHeaders(key, value string) { r.Headers[key] = value } func exampleResponse() { var ( response Response headers map[string]string ) headers = make(map[string]string) headers["Server"] = "GitHub.com" headers["Status"] = "Ok" response.Headers = headers response.Code = 200 response.Result = []byte("hello world") fmt.Println(response.GetAttrCode()) fmt.Println(response.GetAttrHeader()) fmt.Println(response.GetAttrResult()) response.SetCode(404) fmt.Println(response) response.SetHeaders("Status", "failed") fmt.Println(response) } func main() { exampleResponse() } >>> 200 map[Server:GitHub.com Status:Ok] [104 101 108 108 111 32 119 111 114 108 100] {404 [104 101 108 108 111 32 119 111 114 108 100] map[Server:GitHub.com Status:Ok]} {404 [104 101 108 108 111 32 119 111 114 108 100] map[Status:failed Server:GitHub.com]}
函数和方法的区别
func NormalFunc(arg int) int { return arg + 1 } func (r *Response) SetCode(code int) { r.Code = code }
Go 方法是作用在接收者(receiver)上的一个函数。接收者可以是几乎任何类型。
但一般选择 结构体 作为接收者。
组合:
匿名字段
在 Golang 中可以通过结构体的组合实现类的继承。
即:将一个结构体A当成另一个结构体B的匿名字段,则 这个结构体B自动拥有A的所有字段和方法。
type Response struct { Code int Result []byte Headers map[string]string } func (r Response) GetAttrCode() int { return r.Code } func (r Response) GetAttrResult() []byte { return r.Result } func (r Response) GetAttrHeader() map[string]string { return r.Headers } func (r *Response) SetCode(code int) { r.Code = code } func (r *Response) SetHeaders(key, value string) { r.Headers[key] = value } type Requests struct { Url string Params string } type CollectionRequests struct { CollectionNumber int Requests Response } func exampleCollectionRequests() { var collectionRequests CollectionRequests collectionRequests.CollectionNumber = 10 collectionRequests.Url = "https://www.example.com" collectionRequests.Params = "name" collectionRequests.Code = 201 collectionRequests.Result = []byte("hello Golang") var headers map[string]string headers = make(map[string]string) headers["status"] = "Good" collectionRequests.Headers = headers fmt.Println(collectionRequests) fmt.Println(collectionRequests.GetAttrCode()) } func main() { exampleCollectionRequests() } >>> {10 {https://www.example.com name} {201 [104 101 108 108 111 32 71 111 108 97 110 103] map[status:Good]}} 201
上文CollectionRequests
拥有两个匿名字段Requests、Response
,则自动拥有这个两个结构体的字段和方法。
内嵌结构体
这个组合的形式会遇到两个问题:
- 字段相同怎么办?即结构体A 有字段 a, 结构体 B 也有字段 a。怎么处理?
- 方法相同怎么办?即结构体A 有方法 methodOne, 结构体 B 也有方法 methodOne。怎么处理?
应该尽量避免命名冲突。同时可以使用多个点号的方法访问字段。方法则优先使用结构体B 的。
type OtherRequests struct { Request Requests Resp Response Code int } func (o OtherRequests) GetAttrCode() { fmt.Println(fmt.Sprintf("Outer Code = %d", o.Code)) fmt.Println(fmt.Sprintf("inner Code = %d", o.Resp.Code)) } func exampleOtherRequests() { var other OtherRequests other.Code = 201 other.Resp.Code = 202 fmt.Println(other) other.GetAttrCode() fmt.Println(other.Resp.GetAttrCode()) } func main() { exampleOtherRequests() } >>> {{ } {202 [] map[]} 201} Outer Code = 201 inner Code = 202 202
格式化显示结构体
type OtherRequests struct { Request Requests Resp Response Code int } func (o OtherRequests) String() string { return fmt.Sprintf("Request = %v , Response = %v , Code = %d", o.Request, o.Resp, o.Code) } func exampleOtherRequests() { var other OtherRequests other.Code = 201 other.Resp.Code = 202 fmt.Println(other) other.GetAttrCode() fmt.Println(other.Resp.GetAttrCode()) } func main() { exampleOtherRequests() } >>> Request = { } , Response = {202 [] map[]} , Code = 201 Outer Code = 201 inner Code = 202 202
完整示例
package main import "fmt" type Response struct { Code int Result []byte Headers map[string]string } type Requests struct { Url string Params string } type OtherRequests struct { Request Requests Resp Response Code int } func (o OtherRequests) GetAttrCode() { fmt.Println(fmt.Sprintf("Outer Code = %d", o.Code)) fmt.Println(fmt.Sprintf("inner Code = %d", o.Resp.Code)) } func (r Response) GetAttrCode() int { return r.Code } func (r Response) GetAttrResult() []byte { return r.Result } func (r Response) GetAttrHeader() map[string]string { return r.Headers } func (r *Response) SetCode(code int) { r.Code = code } func (r *Response) SetHeaders(key, value string) { r.Headers[key] = value } func (o OtherRequests) String() string { return fmt.Sprintf("Request = %v , Response = %v , Code = %d", o.Request, o.Resp, o.Code) } func exampleOtherRequests() { var other OtherRequests other.Code = 201 other.Resp.Code = 202 headers := make(map[string]string) headers["status"] = "Good" other.Resp.Headers = headers other.Resp.Result = []byte("hello Golang") other.Request.Url = "https://www.example.com" other.Request.Params = "name" fmt.Println(other) other.GetAttrCode() fmt.Println(other.Resp.GetAttrCode()) } func main() { exampleOtherRequests() }
输出:
Request = {https://www.example.com name} , Response = {202 [104 101 108 108 111 32 71 111 108 97 110 103] map[status:Good]} , Code = 201 Outer Code = 201 inner Code = 202 202