分享
  1. 首页
  2. 文章

Go-再论struct

u013344915 · · 1650 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

简介

Go-Structure对struct做了简单的介绍,本文参考如下书目继续丰富本专题。

  • 《Web Development with Go》 Chapter 3
  • 《The Go Programming Language》4.4 Page99

pointer and nonpointer method receiver

Go-Structure一文给出的示例代码中,使用的都是pointer receiver。事实上,也可以使用nonpointer receiver。事实上,也可以使用nonpointer

示例:

package main 
import (
 "fmt"
)
type Point struct {
 x, y int 
}
func (p Point) GetX() int {
 return p.x
}
func (p Point) GetY() int {
 return p.y
}
func (p *Point) SetX(ix int) {
 (*p).x = ix
}
func (p *Point) SetY(iy int) {
 (*p).y = iy
}
func (p *Point) SetY2(iy int) {
 p.y = iy
}
func (p Point) SetY3(iy int) {
 p.y = iy
}
func test1() {
 p := Point{1, 2}
 fmt.Print(p, "\t")
 fmt.Print("x=", p.GetX(), "\t")
 fmt.Print("y=", p.GetY(), "\t")
 p.SetX(3)
 p.SetY(4)
 fmt.Print(p, "\t")
 (&p).SetX(5)
 (&p).SetY(6)
 fmt.Print(p, "\t")
 fmt.Println()
}
// SetY() -> SetY2()
func test2() {
 p := Point{1, 2}
 fmt.Print(p, "\t")
 fmt.Print("x=", p.GetX(), "\t")
 fmt.Print("y=", p.GetY(), "\t")
 p.SetX(3)
 p.SetY2(4)
 fmt.Print(p, "\t")
 (&p).SetX(5)
 (&p).SetY2(6)
 fmt.Print(p, "\t")
 fmt.Println()
}
// SetY() -> SetY3()
func test3() {
 p := Point{1, 2}
 fmt.Print(p, "\t")
 fmt.Print("x=", p.GetX(), "\t")
 fmt.Print("y=", p.GetY(), "\t")
 p.SetX(3)
 p.SetY3(4)
 fmt.Print(p, "\t")
 (&p).SetX(5)
 (&p).SetY3(6)
 fmt.Print(p, "\t")
 fmt.Println()
}
func test4() {
 p := &Point{1, 2}
 fmt.Print(p, "\t")
 fmt.Print("x=", p.GetX(), "\t")
 fmt.Print("y=", p.GetY(), "\t")
 p.SetX(3)
 p.SetY(4)
 fmt.Print(p, "\t")
 //calling method SetX with receiver &p (type **Point) requires explicit dereference
 //(&p).SetX(5)
 //(&p).SetY(6)
 //fmt.Print(p, "\t")
 fmt.Println()
}
/*
D:\examples>go run helloworld.go
test1: {1 2} x=1 y=2 {3 4} {5 6}
test2: {1 2} x=1 y=2 {3 4} {5 6}
test3: {1 2} x=1 y=2 {3 2} {5 2}
test4: &{1 2} x=1 y=2 &{3 4}
D:\examples>
*/
func main() {
 fmt.Print("test1: ")
 test1()
 fmt.Print("test2: ")
 test2()
 fmt.Print("test3: ")
 test3()
 fmt.Print("test4: ")
 test4()
}

要点

copied from:《Web Development with Go》 Chapter 3, Page 39

If you want to modify the data of a receiver from the method, the receiver must be a pointer

If the struct has a pointer receiver on some its methods, it is better to use it for the rest of the methods because it enables better consistency and predictability for the struct behaviors.

pointer & dot notation

这里再介绍指针类型和.操作符的特殊意义。在前面的例子中,有如下代码:

func (p *Point) SetY2(iy int) {
 p.y = iy
}

其等价于:

func (p *Point) SetY2(iy int) {
 (*p).y = iy
}

这种语法是Go中非常特殊的一点。这种语法的证据源于《The Go Programming Language》4.4 Page 100,代码如下:

type Employee struct {
 ID int
 Name string
 Address string
 DoB time.Time
 Position string
 Salary int
 ManagerID int
}

The dot notation also works with a pointer to a struct:

var employeeOfTheMonth *Employee = &dilbert
employeeOfTheMonth.Position += " (proactive team player)"

The last statement is equivalent to

(*employeeOfTheMonth).Position += " (proactive team player)"

Go指针的这种语法可以简化代码。

结构自嵌套

一个结构S内部不能有S成员,但可以有指向S的成员(指针 *S).

type tree struct {
 value int
 left, right *tree
}

比较结构体对象

Go中不能重载==操作符,对于要比较(同一种)结构体的两个对象,则要求其每个field都是可以比较的。而且在比较的时候,是按照每个field依次比较。也可以自定义比较的函数,比如Equals()。

package main 
import (
 "fmt"
)
type Point struct {
 x, y int 
}
func (p Point) GetX() int {
 return p.x
}
func (p Point) GetY() int {
 return p.y
}
func (p *Point) SetX(ix int) {
 p.x = ix
}
func (p *Point) SetY(iy int) {
 p.y = iy
}
func (p *Point) Equals(point Point) bool {
 return p.x == point.x
}
func Equals(p1 Point, p2 Point) bool {
 return p1.x == p2.x
}
func main() {
 p1 := Point{1, 2}
 p2 := Point{x:1, y:2}
 p3 := Point{1, 3}
 fmt.Println(p1 == p2, p2 == p3) // true, false
 fmt.Println(p1.x == p2.x && p1.y == p2.y) // true. Equals to "p1 == p2"
 fmt.Println(p1.Equals(p3)) // true
 fmt.Println(Equals(p2, p3)) // true
}

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:u013344915

查看原文:Go-再论struct

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1650 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏