Redian新闻
>
golang结构体看这篇就够啦

golang结构体看这篇就够啦

公众号新闻


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\n", 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\n", p.Name)}



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

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

1.4 接收者

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

package main
import "fmt"

type Person struct { Name string Age int8 }

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

func (p *Person) GetAge() { fmt.Printf("My age: %d\n", 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值接收者

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

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

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

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


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 }

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

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

package main
import "fmt"
type Person struct { Name string Age int8 }

func (p Person) GetName() { fmt.Printf("My name: %s\n", p.Name)}
type Student struct { ID int Score float32 Person }
func (s Student) GetScore() { fmt.Printf("My score: %v\n", s.Score)}
func main() { p := Student{ ID: 1, Score: 98, Person: Person{ Name: "zhangsan", Age: 18, }, }
fmt.Printf("My age: %d\n", p.Age) fmt.Printf("My age p.Person.age: %d\n", p.Person.Age)
p.GetScore() p.GetName() p.Person.GetName() }

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

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

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

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

本质是: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\n", p.Name)}
func main() { p := Person{Name: "zhangsan", Age: 18}
getName := p.GetName getName()
fmt.Println("--------分割线-------") pGetName := Person.GetName pGetName(p) }

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

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

链接:https://juejin.cn/post/7305294847555698727

(版权归原作者所有,侵删)


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
Heraclitus One cannot step twice into the same river西雅图滑雪场哪家强? 看这篇就够啦在新加坡开银行户口,看这篇避坑指南就够了大模型「幻觉」,看这一篇就够了 | 哈工大华为出品Linux 网络技术栈,看这篇就够了,建议收藏慢慢看!孩子申请顶尖美高,家长也要面试?如何应对招生官提问,看这一篇就够了!湾区人的周末,有这家超市就够啦!三波大促独享,全场满68减15时尚管理学什么?怎么申?看这一篇就够了!墨尔本10月下旬免费活动有哪些,看这一篇就够了!为什么好的奶粉里 DHA 必不可少?奶粉到底怎么选?看这一篇就够了!香港研究生留学适合我么?看这一篇就够了【最后10份】搞定CFA英文,用这个2000词金融词汇就够啦!学费、生活费、托儿费,政府一年补贴$28000!全职妈妈重返职场,看这篇就够了2024年加拿大福利大盘点!最高能拿近$20000!看这一篇就够啦!《呼啸山庄》重译09H超全!2024全球移民趋势盘点,移民看这篇就够了年度手机大盘点!选购指南看这篇就够了……身份问题 | OPT相关知识,看这一篇就够了!由黛安的婚禮所想起的新西兰这么多党,到底该投谁?别慌!NZ各政党最全政策汇总,看这一篇就够了!《歌德堡变奏曲1362》向日葵,友情常在【亚洲专辑】奈良景点:看这一篇就够了纽约万圣活动,看这篇就够!谷歌Offer怎么拿:看这一篇就够了!西雅图秋日hiking路线推荐,新手看这篇就够!2024年,澳洲签证及移民政策将迎来哪些重大变化?看这一篇就够了保姆级 Stable Diffusion 教程,看完这篇就够了!西雅图感恩节餐食指南,看这篇就够啦!中基协发〔2023〕21号22号《私募投资基金备案指引(证券、股权)》,看这篇就够了想学习拍摄纪录片?看这篇就够了时尚管理学什么?怎么申?看这篇就够了!读新加坡国际学校必备什么申请材料,看这篇就够了!干货 | 想知道在美国开餐馆需要多少钱?看这篇就够了!在美国能买到哪些菌菇?松露、松茸、鸡油菌、牛肝菌...中英对照,一文就够啦!
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。