0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

golang结构体实例代码

马哥Linux运维 来源:稀土掘金 2023-11-28 10:35 次阅读

struct概述

结构体是go语言最重要的数据结构之一,go和其它编程语言不一样,它没有类的概念,类比过来struct就相当于其它语言中的类,因此十分重要。

结构体这部分涉及到的知识点页比较多,此文偏长,请耐心阅读。

1. 认识结构体

直接说语法往往非常枯燥,在正式开始前,我们先来看一段简单的结构体代码,建立整体感知,后续我们再一一细说其中的知识点。


package main

import "fmt"


type Person struct {
  Name string 
  Age  int8   
}


func (p Person) GetName() {
  fmt.Printf("My name: %s
", p.Name)
}

func main() {
  p := Person{
    Name: "zhangsan",
    Age:  18,
  }


  p.GetName()
}

看到了吧,还是很简单的,跟着注释你大概已经看懂了如何使用。下面我们拆分成知识点细细分析

1.1 如何定义

它按照如下方式定义(PS: 它还可以代标签,为简单起见,这里暂且不讨论)

type 结构体名 struct {
  字段名1 字段类型1
  字段名2 字段类型2
  .....
}

1.2 实例化

主要有几种方式:


var p = new(Person) 
var p Person        
var p = Person{}    


p := Person{
  Name: "zhangsan",
  Age:  18,
}

p := Person{"zhangsan", 18}

实际例化后我们可以通过obj.字段名的方式调出值,如上例中p.Name

1.3 方法

结构体方法,对应到面向对象语言中就是实例方法.

在上例中,如下部分:


func (p Person) GetName() {
  fmt.Printf("My name: %s
", p.Name)
}


方法和函数有什么主要区别呢?

方法它有接收者,而函数没有

1.4 接收者

接收者既可以是值也可以是指针类型,我们看下:


package main

import "fmt"


type Person struct {
  Name string 
  Age  int8   
}

func (p Person) GetName() {
  fmt.Printf("My name: %s
", p.Name)
}

func (p *Person) GetAge() {
  fmt.Printf("My age: %d
", p.Age)
}


func main() {
  p1 := Person{Name: "张三", Age: 18}  
  p2 := &Person{Name: "李四", Age: 16} 


  
  p1.GetName()
  p1.GetAge()


  fmt.Println("---------分割线-------")
  
  p2.GetName()
  p2.GetAge()
}

我们可以发现,无论接收者是值类型还是指针类型,它们在调用上却不会有任何区别,这是因为go编译器会悄悄自动帮我转换, nice!

1.5 指针接收者or值接收者

那么什么时候使用值接收者啥时候用指针接收者呢?

在go中一般约定,同一个struct接收者类型保持一致(要么全是指针接收者,要么全是值接收者

值接收者:结构体相对较小(拷贝成本不高),不需要改变结构体内部值场景

指针接收者:结构体比较大(拷贝成本高),需要改变结构体内部值场景

2. 匿名字段及嵌套

匿名字段可以说是结构体最有用的功能,使用的地方比比皆是,下面我们来看下

2.1 匿名字段

所谓匿名字段指的是在结构体中字段名可以不用显示写出来,比如:


package main


import "fmt"


type Data struct {
  uint8 
        
}


func main() {
  d := Data{8}
  
  fmt.Println(d.uint8)
}

关键点在于字段名 == 类型名

2.2 结构体嵌套

在开始之前我们来看下两个结构体


type Person struct {
  Name string 
  Age  int8   
}

type Student struct {
  ID    int     
  Name  string  
  Age   int8    
  Score float32 
}

我们会发现学生结构体和人结构体相比只多了两个字段(ID和Score)分别定义有点浪费?另外人和学生有许多相似的地方,某些时候Person结构体中的方法,Student同样也需要,如果分别写两份相同的方法,也很浪费?

好啦!在go中可以通过嵌套解决,直接看代码


package main


import "fmt"


type Person struct {
  Name string 
  Age  int8   
}

func (p Person) GetName() {
  fmt.Printf("My name: %s
", p.Name)
}


type Student struct {
  ID     int     
  Score  float32 
  Person         
}


func (s Student) GetScore() {
  fmt.Printf("My score: %v
", s.Score)
}


func main() {
  p := Student{
    ID:    1,
    Score: 98,
    Person: Person{ 
      Name: "zhangsan",
      Age:  18,
    },
  }


  
  fmt.Printf("My age: %d
", p.Age)                     
  fmt.Printf("My age p.Person.age: %d
", p.Person.Age) 


  p.GetScore()       
  p.GetName()        
  p.Person.GetName() 
}

上面的注释已经非常详细,这里总结下规律:

匿名结构体嵌套,会有如下效果:

匿名结构体中字段,当前结构体可以直接调用

匿名结构体方法,当前结构体可以直接调用

本质是:go在字段查找时,现在本结构体中找,如果找不到则到匿名结构体中查找;方法同理

2.3 匿名结构体嵌套经典使用

数据库表设计中: 我们可以把常用的字段抽出来成一个结构体,其它结构体只需要引入就可以扩展其中字段以及方法,比如:


package main


import (
  "fmt"
  "time"
)


type BaseTable struct {
  ID        int
  CreatedAt time.Time
  UpdatedAt time.Time
}


type User struct {
  Name      string
  BaseTable 
}

3. 方法值和方法表达式

方法值和方法表达式类似于函数表达式,我们可以将函数表达式当作变量传递,方法值和方法表达式也是一样,文字上不太容易明白,直接看代码


package main


import (
  "fmt"
)


type Person struct {
  Name string
  Age  int8
}


func (p Person) GetName() {
  fmt.Printf("My name: %s
", p.Name)
}


func main() {
  p := Person{Name: "zhangsan", Age: 18}


  
  getName := p.GetName
  getName() 


  fmt.Println("--------分割线-------")
  
  pGetName := Person.GetName
  pGetName(p) 
}

它可以做为变量取出,因此可以实现复杂精巧场景下的使用,举例这里不做举例,方法值和方法表达式的区别在于:

方法表达式需要把接收者做为参数传入

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 指针
    +关注

    关注

    1

    文章

    473

    浏览量

    70361
  • 编译器
    +关注

    关注

    1

    文章

    1577

    浏览量

    48614
  • 数据结构
    +关注

    关注

    3

    文章

    564

    浏览量

    39899
  • 面向对象
    +关注

    关注

    0

    文章

    64

    浏览量

    9923
  • Struct
    +关注

    关注

    0

    文章

    29

    浏览量

    10817

原文标题:golang结构体看这篇就够啦

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Golang接口的作用和应用场景

    Golang(Go)作为一门现代的静态类型编程语言,提供了许多强大的特性,其中之一便是接口(interface)。接口是Golang中的一个核心概念,它具有广泛的应用场景,可以帮助开发者实现代码
    的头像 发表于 12-05 10:44 628次阅读

    漫谈C语言结构

      相信大家对于结构都不陌生。在此,分享出本人对c语言结构的学习心得。如果你发现这个总结中有你以前所未掌握的,那本文也算是有点价值了。当然,水平有限,若发现不足之处恳请指出。
    发表于 11-15 15:59

    请问怎么在树莓派上从源代码构建Golang

    就是指导你如何在树莓派上从源代码来构建Go语言。 Google暂时还没有为树莓派提供预构建好的Golang二进制包。尽管在写作本文时已经有一个针对Raspbian系统的Golang包了,但版本较老
    发表于 05-16 07:55

    Golang怎么实现UTS隔离

    Golang实现UTS隔离
    发表于 08-23 14:44

    串口传输结构是什么意思

    串口传输 结构就是 把结构 转换为 数组 ,然后传输 数组中的 char。即 struct- - - - - - ->> char [ ] ;然后 char
    发表于 07-14 08:34

    使用结构的主要作用

    结构作用(STM32)来源:正点原子MDK 中很多地方使用结构以及结构指针,下面总结一下其
    发表于 08-24 07:54

    结构变量的定义与使用变量访问结构成员

    知识点回顾关于找最大公共子串的两种解题方法结构的定义(3种)结构变量的定义与使用变量访问结构
    发表于 12-17 07:10

    消息队列传递结构指针和结构异同

    FreeRTOS消息队列 传递结构指针和结构异同1 消息队列传递结构指针和
    发表于 02-11 07:02

    利用golang优雅的实现单实例分享

    1、利用golang优雅的实现单实例平时编写代码过程中,经常会遇到对于全局角度只需运行一次的代码,比如全局初始化操作,设计模式中的单例模式。针对单例模式,java中又出现了饿汉模式、懒
    发表于 10-17 16:46

    golang的调度模型-GPM 模型的源码结构

    【导读】GMP 模型是让 go 语言轻量快速高效的重要调度模型,本文从 GMP 源码出发直观地解析了这一模型。 这篇文章就来看看 golang 的调度模型-GPM 模型的源码结构。 Go 版本
    的头像 发表于 07-06 11:55 1918次阅读

    golang orm库xorm的使用和项目结构

      本文介绍了 golang orm 库 xorm 的使用和项目结构。 xorm 官方介绍:xorm 是一个简单而强大的 Go 语言 ORM 库。 通过它可以使数据库操作非常简便。xorm 的目标
    的头像 发表于 10-29 10:36 2381次阅读
    <b class='flag-5'>golang</b> orm库xorm的使用和项目<b class='flag-5'>结构</b>

    鸿蒙应用实例代码

    鸿蒙应用实例代码,仅供参考。
    发表于 09-27 14:56 11次下载

    初探Golang内联

    今天我们来聊聊 Golang 中的内联。
    的头像 发表于 12-13 09:51 616次阅读

    解析Golang定时任务库gron设计和原理

    正巧,最近看到了 gron 这个开源项目,它是用 Golang 实现一个并发安全的定时任务库。实现非常简单精巧,代码量也不多。今天我们就来一起结合源码看一下,怎样基于 Golang 的能力做出来一个【定时任务库】。
    的头像 发表于 12-15 13:57 946次阅读

    GoLang的安装和使用

    GoLang的安装和使用
    的头像 发表于 01-13 14:06 1032次阅读
    <b class='flag-5'>GoLang</b>的安装和使用