Skip to main content

golang 结构体解析

gogolang结构体About 3 min

刚开始接触go, 直观的感觉就是--好奇葩的语言. 对于面向对象的中毒用户, 又一时难以接受里面的一些做法. go不是一门面向对象编程的语言, 没有对象和继承的概念, 也没有多态与重载. go表示一个对象的概念是通过构造体实现的. 这一篇文章我们就详细看看构造体的使用.

长什么样

go语言的设计很有c的风格, 包括这个结构体的概念.
通过如下方式可以定义一个构造体:

type Person struct {
    Name string
    Age int
}

对一个构造体赋值, 有很多种方式:

    // 声明一个结构体实例, 并赋初值 字段: value
    person := Person{
        Name: "aaa",
        Age: 23,
    }
    // 设置空值
    person = Person{}
    // 按照字段顺序进行赋值
    person = Person{"bbb", 23}
    // 也支持指定某个字段赋值
    person = Person{Name: "aaa"}

还可以通过new关键字, 赋值直接.下面的属性赋值, 不过要注意此时的person为指针类型

    person := new(Person)
    person.Name = "zhangxu"
    person.Age = 23

new的作用和&Person{}的作用相同

绑定方法

将方法与结构体进行绑定可以参考如下示例

func (p *Person) changeAge() {
    p.Age += 100
}

之后就可以通过person.changeAge()进行调用.

这里要注意一点, 我们关联的是指针*Person, 此时拷贝的为地址, 如果使用Person则拷贝的为原来的数据, 因此改变内部属性将不会作用到原有变量. 实际表现为Age没有加100

构造器

很遗憾没有构造器. 但是可以使用方法实现:

func NewPerson(name string, age int) Person {
   return Person{name, age}
}

person := NewPerson("zhangsna", 12)就可以完成声明和初始化

组合

这是将一个结构包含进另一个结构的行为

下面的例子中我们在Person中增加了一个Class, 注意非同名字段可以直接获取, 同名字段只能逐步调用.

type Class struct {
    Name string
    Score int
}
type Person struct {
    Name string
    Age int
    *Class
}

func main() {
    person := Person{"zhangsna", 12, &Class{"语文", 83}}
    fmt.Println(person)
    fmt.Println(person.Score)
    fmt.Println(person.Name)
    fmt.Println(person.Class.Name)
}

传值还是传指针

如果结果体内部以值的方式组合一个结构体, 赋值时自然要使用结构体的方式进行赋值, 而不是使用指针.

type Class struct {
    Name string
    Score int
}
type Person struct {
    Name string
    Age int
    Class
}

func main() {
    person := Person{"zhangsna", 12, Class{"语文", 83}}
    fmt.Println(person)
    fmt.Println(person.Score)
    fmt.Println(person.Name)
    fmt.Println(person.Class.Name)
}

你会发现这两个程序(与上面一节)输出结果是相同的

个人理解, 就结构体本事讨论没有什么意义, 应该要结合具体的方法使用, 如果你需要修改结构体的值, 那么对应的方法参数肯定需要传指针
如果结构体中是用的是指针, 那么直接传过去就好了. 如果是第二种方式就通过&取地址传过去, 也可以.

你可以运行一下下面的程序

type Class1 struct {
    Name string
    Score int
}
type Class2 struct {
    Name string
    Score int
}
type Person struct {
    Name string
    Age int
    *Class1
    Class2
}

func main() {

    person := Person{"zhangsna", 12,
        &Class1{"语文", 83},
    Class2{"数学", 83}}


    changeClass1Score(person.Class1)
    changeClass2Score(&person.Class2)

    fmt.Println(person.Class1)
    fmt.Println(person.Class2)

}

func changeClass1Score(c *Class1) {
    c.Score += 10
}
func changeClass2Score(c *Class2) {
    c.Score += 10
}

What do you think?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v3.0.0-alpha.10