Go语言学习之旅--结构体

Posted 赵jc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言学习之旅--结构体相关的知识,希望对你有一定的参考价值。

结构体


在定义结构体之前,我们先来看看什么是类型定义和类型别名

go语言类型定义

类型定义的语法

type NewType Type

举例

func main() 
	//类型定义
	type MyInt int
	//i为MyInt类型
	var i MyInt
	i = 100 
	fmt.Printf("i: %v i: %T\\n", i, i)

go语言类型别名

类型别名语法

type NewType = Type

举例

func main() 
	//类型别名定义
	type MyInt2 =  int
	//i还是int类型
	var i MyInt2
	i = 100 
	fmt.Printf("i: %v i: %T\\n", i, i)

go语言类型定义和类型别名的区别

  • 1.类型定义相当于定义了一个全新的类型,与之前的类型不同;但是类型别名并没有定义一个新的类型,而是使用一个别名来替换之前的类型
  • 2.类型别名只会在代码中存在,在编译完成之后并不会存在该别名
  • 3.因为类型别名和原来的类型是一致的,所以原来类型所拥有的方法,类型别名中也可以调用,但是如果是重新定义的一个类型,那么不可以调用之前的任何方法

结构体

go语言结构体的定义

结构体的定义和类型定义类似,只不过多了一个struct关键字

  • 语法结构如下:
type struct_variable_type struct 
   member definition;
   member definition;
   ...
   member definition;

  • type:结构体定义关键字
  • struct_variable_type:结构体类型名称
  • struct:结构体定义关键字
  • member definition:成员定义

举例
下面我们定义一个人的结构体Person

type Person struct 
    id    int
    name  string
    age   int
    email string

以上我们定义一个Person结构体,有四个成员,来描述一个Person的信息。类型相同可以合并到一行,例如:

type Person struct 
    id, age     int
    name, email string

声明一个结构体变量

声明一个结构体变量和声明一个普通变量相同,例如:

var tom Person
fmt.Printf("tom: %v\\n", tom)
kite := Person
fmt.Printf("kite: %v\\n", kite)

结果
tom: 0 0  
kite: 0 0  

结构体成员,在没有赋值之前都是零值。

结构体的初始化

  • 未初始化的结构体

成员都是默认值 int 0 float 0.0 bool false string nil nil

package main

import "fmt"

func main() 
    type Person struct 
        id, age     int
        name, email string
    

    var tom Person
    fmt.Printf("tom: %v\\n", tom)

  • 使用键值对对结构体进行初始化
package main

import "fmt"

func main() 
    type Person struct 
        id, age     int
        name, email string
    

    kite := Person
        id:    1,
        name:  "kite",
        age:   20,
        email: "zjc.com",
    
    fmt.Printf("kite: %v\\n", kite)


  • 使用值的列表初始化

注意:

  1. 必须初始化结构体的所有字段。
  2. 初始值的填充顺序必须与字段在结构体中的声明顺序一致。
  3. 该方式不能和键值初始化方式混用。
package main

import "fmt"

func main() 
    type Person struct 
        id, age     int
        name, email string
    

    kite := Person
        1,
        20,
        "kite",
        "zjc.com",
    
    fmt.Printf("kite: %v\\n", kite)

  • 部分成员初始化
package main

import "fmt"
func main() 
    type Person struct 
        id, age     int
        name, email string
    

    kite := Person
        id:   1,
        name: "kite",
    
    fmt.Printf("kite: %v\\n", kite)

访问结构体成员

可以使用点运算符(.),来访问结构体成员,例如:

package main

import "fmt"

func main() 
    type Person struct 
        id, age     int
        name, email string
    

    var tom Person
    tom.id = 1
    tom.name = "tom"
    tom.age = 20
    tom.email = "zjc.com"
    fmt.Printf("tom: %v\\n", tom)


匿名结构体

如果结构体是临时使用,可以不用起名字,直接使用,例如:

package main
import "fmt"
func main() 
    var dog struct 
        id   int
        name string
    
    dog.id = 1
    dog.name = "旺财"
    fmt.Printf("dog: %v\\n", dog)

结构体指针

举例

package main

import "fmt"

func main() 
    type Person struct 
        id   int
        name string
    

    var tom = Person1, "tom"

    var p_person *Person
    p_person = &tom
    fmt.Printf("tom: %v\\n", tom)
    fmt.Printf("p_person: %p\\n", p_person)
    fmt.Printf("*p_person: %v\\n", *p_person)

使用new关键字创建结构体指针

我们还可以通过使用new关键字对结构体进行实例化,得到的是结构体的地址,例如:

package main

import "fmt"

func main() 
    type Person struct 
        id   int
        name string
    
    var p_person = new(Person)
    fmt.Printf("p_person: %T\\n", p_person)

访问结构体指针成员

访问结构体指针成员,也使用点运算符(.),例如:

package main

import "fmt"

func main() 
    type Person struct 
        id   int
        name string
    

    var p_person = new(Person)
    fmt.Printf("p_person: %T\\n", p_person)

    p_person.id = 1
    p_person.name = "tom"
    fmt.Printf("*p_person: %v\\n", *p_person)

结构体作为函数参数

定义

go结构体可以像普通变量一样,作为函数的参数,传递给函数,这里分为两种情况:

  • 直接传递结构体,这是是一个副本(拷贝),在函数内部不会改变外面结构体内容。
  • 传递结构体指针,这时在函数内部,能够改变外部结构体内容。

直接传递结构体

package main

import "fmt"

type Person struct 
    id   int
    name string


func showPerson(person Person) 
    person.id = 1
    person.name = "kite"
    fmt.Printf("person: %v\\n", person)


func main() 
    person := Person1, "tom"
    fmt.Printf("person: %v\\n", person)
    fmt.Println("----------------")
    showPerson(person)
    fmt.Println("----------------")
    fmt.Printf("person: %v\\n", person)


运行结果:
person: 1 tom
----------------
person: 1 kite
----------------
person: 1 tom

从运行结果可以看出,函数内部改变了结构体内容,函数外面并没有被改变。

传递结构体指针

package main

import "fmt"

type Person struct 
    id   int
    name string


func showPerson(person *Person) 
    person.id = 1
    person.name = "kite"
    fmt.Printf("person: %v\\n", person)


func main() 
    person := Person1, "tom"
    fmt.Printf("person: %v\\n", person)
    fmt.Println("----------------")
    showPerson(&person)
    fmt.Println("----------------")
    fmt.Printf("person: %v\\n", person)


运行结果
person: 1 tom
----------------
person: &1 kite
----------------
person: 1 kite

从运行结果,我们可以看到,调用函数后,参数被改变了。

嵌套结构体

go语言没有面向对象编程思想,也没有继承关系,但是可以通过结构体嵌套来实现这种效果。

下面通过实例演示如何实现结构体嵌套,加入有一个人Person结构体,这个人还养了一个宠物Dog结构体。

下面我们来看一下:
Dog结构体

type Dog struct 
    name  string
    color string
    age   int

Person结构体

type person struct 
    dog  Dog
    name string
    age  int

package main

import "fmt"

type Dog struct 
    name  string
    color string
    age   int


type person struct 
    dog  Dog
    name string
    age  int

访问它们
func main() 
    var tom person
    tom.dog.name = "花花"
    tom.dog.color = "黑白花"
    tom.dog.age = 2

    tom.name = "tom"
    tom.age = 20

    fmt.Printf("tom: %v\\n", tom)

运行结果

tom: 花花 黑白花 2 tom 20

golang继承

golang本质上没有oop的概念,也没有继承的概念,但是可以通过结构体嵌套实现这个特性。

package main

import "fmt"

type Animal struct 
    name string
    age  int


func (a Animal) eat() 
    fmt.Println("eat...")


func (a Animal) sleep() 
    fmt.Println("sleep")


type Dog struct 
    Animal


type Cat struct 
    Animal


func main() 
    dog := Dog
        Animal
            name: "dog",
            age:  2,
        ,
    

    cat := Cat
        Animalname: "cat",
            age: 3,
    

    dog.eat()
    dog.sleep()

    cat.eat()
    cat.sleep()


golang构造函数

golang没有构造函数的概念,可以使用函数来模拟构造函数的的功能。

例如

package main

import "fmt"

type Person struct 
    name string
    age  int


func NewPerson(name string, age int) (*Person, error) 
    if name == "" 
        return nil, fmt.Errorf("name 不能为空")
    
    if age < 0 
        return nil, fmt.Errorf("age 不能小于0")
    
    return &Personname: name, age: age, nil


func main() 
    person, err := NewPerson("tom", 20)
    if err == nil 
        fmt.Printf("person: %v\\n", *person)
    

本篇文章借鉴https://blog.csdn.net/geek99_guo/article/details/121752993?spm=1001.2014.3001.5502写的,如有不对可以评论留言

以上是关于Go语言学习之旅--结构体的主要内容,如果未能解决你的问题,请参考以下文章

Go语言学习之旅--结构体

go语言学习笔记 — 基础 — 高级数据类型 — 结构体:初始化结构体的成员变量

Go语言基础:结构体

Go语言基础:结构体

go语言基础函数,数组,指针,结构体

go语言基础函数,数组,指针,结构体