从零开始学GO ---- 结构体和方法

用 Go 语言从零开始打造你的端口转发工具 从项目初始化到配置解析与核心逻辑实现,每一步都旨在帮助你加深对Go语言网络编程的理解。本工具支持TCP流量转发,可通过配置文件灵活配置。 阅读详情

从零开始学GO ---- 结构体和方法

struct

Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念。Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。

struct结构中的类型可以是任意类型,struct的存储空间是连续的,其字段按照声明时候的顺序存放(注意字段之间有对齐要求)

struct有两种类型:

  • struct类型字面量

    struct{
        FeildName FeildType
        FeildName FeildType
        FeildName FeildType
    }
    
  • 使用type声明的自定义struct类型

    type TypeName struct{
        FeildName FeildType
        FeildName FeildType
        FeildName FeildType
    }
    

例如定义一个人的信息,包括名字、年龄、城市:

type person struct {
	name string
	city string
	age  int8
}

只有当结构体实例化时,才会真正地分配内存。也就是必须实例化后才能使用结构体的字段。

struct初始化

定义一个Person结构:

type Person struct{
    name string
    age int
} 
  • 按照字段顺序初始化

    	a:=Person("Tom",19)
    
    	b:=Person{"James",20}
    

    但一旦结构体增加字段,将不得不修改初始化语句

  • 指定字段名进行初始化

    	a := Person{
    		name: "Tom",
    		age:  19}
    

    哪怕结构增加字段,也不需要修改初始化语句

  • 使用new内置函数,字段默认初始化威其类型的零值,返回值是指向结构的指针

    p:=new(Person)
    //name为"",age是0
    
  • 一次初始化一个字段

    	p:=Person{}
    	p.name="Tom"
    	p.age=19
    

    这个通常用于实例化某个具体字段,不常用来进行初始化

  • 使用构造函数进行初始化

    Go语言的结构体没有构造函数,需要自己实现, 因为struct是值类型,如果结构体比较复杂的话,值拷贝性能开销会比较大,所以构造函数返回的是结构体指针类型会更高效

    func newPerson(name string, age int8) *person {
    	return &person{
    		name: name,
    		age:  age,
    	}
    }
    p := newPerson("Tom",19)
    
匿名字段

定义struct的过程中,如果字段只给出字段类型,没有给出字段名,则这样的字段为匿名字段。匿名字段并不代表没有字段名,而是默认会采用类型名作为字段名,结构体要求字段名称必须唯一,因此一个结构体中同种类型的匿名字段只能有一个。

type Person struct {
	string            //匿名字段
	int               //匿名字段
}

func main() {
	p1 := Person{
		"Tom",
		18,
	}
}
结构字段

结构字段可以是任意类型,基本类型、接口类型、指针类型、函数类型都可以作为struct的字段。内嵌自身的指针是实现链表、树等复杂结构的基础。

type node struct{           //简单的双向链表的结点
    //指向自身类型的指针
    next,prev *Element
    value int
}

方法

Go语言的方法类型是一种对类型行为的封装,方法就是一种作用于特定类型变量的函数,这种特定类型变量叫做接收者(Receiver)

为命名类型定义方法的格式:

//类型方法接收者是值类型
func (t TypeName) MethodName(ParamList)(ReturnList){
    //method body
}
//类型方法接收者是指针
func (t *TypeName) MethodName(ParamList)(ReturnList){
    //method body
}

示例:写一个求 slice 的和的函数

type SliceInt []int

func (s SliceInt) Sum() int {
	sum := 0
	for _, i := range s {
		sum += i
	}
	return sum
}

func main() {
	var s SliceInt = []int{1, 2, 3, 4}
	fmt.Println(s.Sum())       //10
}
  • 可以为命名类型增加方法,非命名类型不可以

    例如不能为[]int类型增加方法,因为[]int是非命名类型。但是可以为[]int命名,从而增加方法

  • 使用type定义的自定义类型是一个新类型,新类型不能调用原有类型的方法,但是底层类型支持的运算可以被继承

    type Map map[string]string
    func (m Map) Print(){
        //底层类型支持的range运算,新类型可用
        for _,key:=range m{
            fmt.Println(key)
        }
    }
    

指针类型的接收者:

指针类型的接收者由一个结构体的指针组成,由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的。

// 使用指针接收者
func (p *Person) SetAge(newAge int8) {
	p.age = newAge
}            //通过指针接收者可以改变原结构体的内容

值类型的接收者:

当方法作用于值类型接收者时,Go语言会在代码运行时将接收者的值复制一份。在值类型接收者的方法中可以获取接收者的成员值,但修改操作只是针对副本,无法修改接收者变量本身。

// 使用值接收者
func (p Person) SetAge2(newAge int8) {
	p.age = newAge
}        //不能修改原结构体的内容

什么时候应该使用指针类型接收者

  • 需要修改接收者中的值
  • 接收者是拷贝代价比较大的大对象
方法调用
  • 一般调用 :TypeInstanceName.MethodName(ParamList)

    type T struct {
    	a int
    }
    
    func (t T) Get() int {
    	return t.a
    }
    func (t *T) Set(i int) {
    	t.a = i
    }
    
    func main() {
    	var t = &T{}
    	t.Set(2)
    	fmt.Println(t.Get())  //2
    }
    
  • 方法值(method value)

    变量x的静态类型是T,M是T的一个方法,x.T被称为方法值。x.T是一个函数类型变量,可以赋值给其他变量

    f:=x.M
    f(args..)
    //<====>等价于
    x.M(args..)
    

    方法值是一个带有闭包的函数变量,接受值被隐式绑定到方法值的闭包环境中,后续调用不需要再显示传递接收者。

    type T struct {
    	a int
    }
    
    func (t T) Get() int {
    	return t.a
    }
    func (t *T) Set(i int) {
    	t.a = i
    }
    func (t *T) Print() {
    	fmt.Println(t.a)
    }
    
    func main() {
    	var t = &T{}
    	//方法值
    	f := t.Set
    	f(2)
    	t.Print()    //2
    	f(3)
    	t.Print()    //3
    }
    
  • 方法表达式

    方法表达式提供一种语法,将类型方法调用显式转换为函数调用,接收者需要显式传进去

    	t := T{a: 1}
    	//方法表达式调用
    	(T).Get(t)
    	//<===>等价
    	f1 := T.Get
    	f1(t)
    
    	f2 := (*T).Print
    	(*T).Set(&t, 1)
    	f2(&t)     //1
    	//<====>
    	f3 := (*T).Set
    	f3(&t, 3)
    	f2(&t)  //3
    

组合

内嵌字段的初始化和访问
package main

import "fmt"

type X struct {
	a int
}
type Y struct {
	X
	b int
}
type Z struct {
	Y
	c int
}

func main() {
	x := X{a: 1}
	y := Y{X: x, b: 2}
	z := Z{Y: y, c: 3}
	//由于字段唯一,因此Z.a等价于Z.Y.X.a
	fmt.Println(z.a, z.Y.a, z.Y.X.a)   // 1 1 1
	z.a = 2
	fmt.Println(z.a, z.Y.a, z.Y.X.a)  //2 2 2
}
//如果字段不唯一,应该精确到具体层次进行初始化和访问
内嵌字段的方法调用

从外向内查,找到可调用的即停止。

package main

import "fmt"

type X struct {
	a int
}
type Y struct {
	X
	b int
}
type Z struct {
	Y
	c int
}

func (x X) Print() {
	fmt.Printf("In X,a=%d\n", x.a)
}

func (x X) XPrint() {
	fmt.Printf("In X,a=%d\n", x.a)
}
func (y Y) Print() {
	fmt.Printf("In Y,b=%d\n", y.b)
}
func (z Z) Print() {
	fmt.Printf("In Z,c=%d\n", z.c)
    z.Y.Print()   //调用的是Y的Print()
	z.Y.X.Print()
}

func main() {
	x := X{a: 1}
	y := Y{X: x, b: 2}
	z := Z{Y: y, c: 3}
    z.Print()  //调用了Z的Print()
	//In Z,c=3
	//In Y,b=2
	//In X,a=1
}
组合的方法集

组合构造的方法集有如下规则:

  1. 若类型S包含匿名字段T,则S的方法集包含T的方法集
  2. 若类型S包含匿名字段*T,则S的方法集包含T和*T方法集
  3. 不管类型S中嵌入的匿名字段是T还是*T, *S方法集总是包含T和*T方法集
dingding:[钉钉]用Golang写的快速安装开发SDK fastwego/dingding A fast development sdk written in Golang 快速开始 & demo go get github.com/fastwego/dingding // 钉钉 AccessToken 管理器 atm := &dingding.DefaultAccessTokenManager{ Id: DingConfig["AppKey"], Name: "access_token", GetRefreshRequestFunc: func() *http.Request { params := url.Values{} params.Add("appkey", DingConfig["AppKey"]) params.Add("appsecret", Ding 立即下载

相关推荐

无人机巡检提速3倍!YOLOv8n+OpenVINO让Jetson Nano跑25FPS,还能多飞25分钟

摘要(149字): 针对无人机巡检中Jetson Nano算力不足导致的帧率低、首次推理延迟高、续航短等问题,提出YOLOv8n+OpenVINO联合优化方案: 模型轻量化:YOLOv8n参数量仅3.2M(较v8s减少71%),Jetson Nano帧率从8FPS提升至15FPS(原生),绝缘子裂纹召回率仅降3%; OpenVINO加速:AUTO模式动态分配CPU/GPU算力,首次推理延迟从500ms降至200ms,帧率再优化至25FPS; 能效提升:功耗降低40%,单次续航延长25分钟。方案已落地电力/林

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1242

go结构体的方法和普通函数

package main import ( "fmt" "math" ) type vertex struct { X, Y float64 } //值接收者是复制一个对象。指针接收者是直接修改地址指向的值 func (v vertex) abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } //这...

dianyin7770的博客 345

零代码构建AI智能体:COZE可视化工作流实战指南

AI智能体(AI Agent)是当前人工智能领域的重要发展方向,它通过模块化设计和工作流驱动,使大语言模型从被动对话转向主动执行。其核心原理在于将复杂的任务分解为可规划、可执行的步骤,并调用外部工具(插件)完成闭环。这一技术价值在于显著降低了自动化流程的开发门槛,让非程序员也能构建实用的数字助手。典型的应用场景包括智能客服、内容自动生成、数据分析和跨系统业务流程自动化。本文以COZE平台为例,深入解析如何通过其直观的可视化界面和丰富的插件生态,像搭积木一样快速搭建如“早安简报生成器”等实用智能体,并分享指令

468

从零开始学Go:轻松掌握Golang基本语法

最新接入DeepSeek-V3模型,点击下载最新版本InsCode AI IDE 从零开始学Go:轻松掌握Golang基本语法 随着技术的快速发展,编程语言的选择变得越来越重要。Go语言(又称Golang)作为一门高效、简洁且易于维护的语言,近年来受到了越来越多开发者的青睐。无论是构建微服务、处理大数据,还是开发高性能后端系统,Go语言都展现出了卓越的能力。然而,对于初学者来说,学习一门新语言可能...

WhiteTiger78的博客 737

AIDC智算中心建设:资源池化核心技术解析

AI 应用的POD在运行的时候,通过池化运行时访问虚拟GPU、执行AI任务,池化运行时拦截对虚拟GPU的访问请求、转递给池化服务代理执行,池化服务代理通过向智算池化控制器查询虚拟GPU所对应的真实智算资源位置、规格,按查询结果分配智算资源、执行AI任务,如果真实的智算资源位于远程计算节点,则由本地池化服务代理将访问请求转递给远程计算节点上的池化服务代理处理,相关通信经由参数面网络。

u013891230的博客 2431

基于Simulink的防空导弹六自由度弹道建模与仿真实战

本文详细介绍了基于Simulink的防空导弹六自由度弹道建模与仿真方法。通过分析导弹动力学原理、Simulink环境配置、气动力建模、推进与控制系统设计等关键环节,提供了一套完整的实战指南。文章特别强调了六自由度模型在防空导弹仿真中的重要性,并分享了常见问题排查与优化建议,为相关领域工程师提供实用参考。

apple5的专栏 868

万字总结:从零开始学 Go

万字总结:从零开始学 Go Go 语言基础教程

weixin_41335923的博客 941

pi-coding-agent 完整详解

pi-coding-agent是一个由Mario Zechner开发的专业AI编程助手,基于Node.js和TypeScript构建。核心功能包括:1)多级思考模式(ThinkingLevel),从none到ultra控制推理深度;2)对话压缩(compaction)管理长对话记忆;3)WebSocket实时通信支持流式交互。该智能体支持代码生成、调试、重构等专业编程任务,采用AI Agent架构,具备工具调用和多轮记忆能力。项目结构通常包含server、agent、config等模块,可通过二次开发扩展功

大坡3D软件开发 2420

从零开始学GO ---- 指针、数组、切片、字典、结构体

从零开始学GO ---- (2) 指针、数组、切片、字典、结构体 指针 Go语言支持指针,指针的声明类型为* T,多级指针声明为** T,通过在变量名前加&获取变量的地址。 不过区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针。因此,实际上,对于Go中的指针,只需要记住两个符号:&(取地址)和*(根据地址取值) var a =11 p:=&a //p是一个指针,*p和a的值都是11 通过传入一个变量的地址,可以实现一个函数中改变该变量的目的: packa

Ding 的博客 472

AI在电商中的搜索优化

自拟标题 《AI技术助力电商搜索优化:深度解析一线大厂面试题及算法编程实践》 概述 随着人工智能技术的不断发展,AI在电商搜索优化中的应用日益广泛。本文将围绕“AI在电商中的搜索优化”这一主题,介绍国内头部一线大厂如阿里巴巴、百度、腾讯、字节跳动等在面试中常见的AI相关面试题和算法编程题,并提供详尽的答案解

AI天才研究院 912

【WRF-Chem Emissions教程第一期】WRF-Chem 排放概述

WRF-Chem 排放概述

WW、forever的博客 852

Go语学习笔记 - 结构体方法接收器 | 从零开始Go语言

Go语学习笔记 - 结构体方法接收器

阿良的博客 2201

ZY1-02D (ZY1E)多光谱数据预处理

资源一号02D卫星(5米光学卫星)于2019年9月12日成功发射,卫星搭载的两台相机,可有效获取115公里幅宽的9谱段多光谱数据以及60公里幅宽的166谱段高光谱数据,其中全色谱段分辨率可达2.5米、 多光谱为10米、高光谱优于30米,高光谱载荷可见近红外和短波红外光谱分辨率分别达到10纳米和20纳米。

热爱分享,热爱记录 4832

探索Go语言的无限可能:《从零开始学Go》

探索Go语言的无限可能:《从零开始学Go》 golang-bookA book on Go, contains fundamentals but also recipes项目地址:https://gitcode.com/gh_mirrors/gol/golang-book 在编程世界里,Go语言以其简洁、高效和并发性能优秀的特点,迅速成为开发者们的宠儿。为了帮助更多的初学者轻松入门Go语言,我们...

gitblog_00031的博客 466

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Go语言入门指南:从零开始学Go

/ 基本函数// 多个参数类型相同,可以简写// 多返回值return 0, errors.New("除数不能为零")// 命名返回值return // naked return,自动返回命名返回值// 可变参数total := 0// 使用Go语言以其简洁、高效和强大的并发支持,成为现代后端开发的重要选择。环境搭建和第一个程序基础语法(变量、常量、数据类型、运算符)控制流程(条件、循环、switch)函数和方法数组、切片和Map结构体和接口错误处理。

好代码自己会说话,烂代码才需要注释来圆谎 4744

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

从零开始学Go之基本(五):结构体

结构体: 声明: type 结构体名 struct{ ​ 结构体内部字段 ​ } 例子: type UserInfo struct { Id string `json:"id"` Name string `json:"name"` Headpicture string `json:"headpicture"` Info string...

weixin_30311605的博客 80

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

从零开始学Go之函数(二):指针与方法

类型别名与类型定义: 类型别名: type 类型别名 = 类型名 type TypeAlias = int TypeAlias 只是 int 的别名,本质上 TypeAlias 与 int 是同一个类型 类型定义: type 新类型名 类型 type NewInt int NewInt 则是一个新的类型,虽然他的实例化可以被赋值int,但是不再...

131

Golang Vue 后台框架 go-admin 从零开始企业级实战视频教程(33 个视频)

Golang 作为后端应该会成为未来几年的主要趋势之一,Vue 又是用得最多的框架,go-admin 是一个很成熟的后台框架,支持市面上几乎所有的需求的框架

求知久久编程学院 1071

从零开始学Golang:AI赋能下的高效编程之旅

开发AI智能应用,就下载InsCode AI IDE,一键接入DeepSeek-R1满血版大模型! 标题:从零开始学Golang:AI赋能下的高效编程之旅 引言 在当今快速发展的科技时代,编程语言的多样性和复杂性对开发者提出了更高的要求。而Golang(Go语言)作为近年来备受推崇的一种编程语言,因其简洁、高效和强大的并发处理能力,逐渐成为许多开发者的首选工具。然而,对于初学者而言,掌握Golan...

SnowflakeJaguar14的博客 1008

#小白学Go-01# 学完Go指南感受,对比一下Go与其他语言

本人以前是C/C++和Python选手,因为以后的工作需要用到Go,所以只好从零开始学习Go。本篇记录一下刚看完Go指南的感受,可能理解还不到位。

xxdsw的博客 355

【Go语言圣经】从零开始学Go----2.程序结构

《Go语言圣经》读书笔记,完整知识点整理,从零开始学Golang

2301_79819426的博客 1136

从零开始构建gRPC的Go服务

第一步首先定义gRPC服务以及方法请求和响应类型。然后在服务定义中定义RPC方法,指定它们的请求和响应类型。一个简单的RPC,其中客户端使用存根向服务端发送请求并等待响应返回,就像正常的函数调用一样。服务端流式RPC,客户端向服务端发送请求并获取流以读回一系列消息。客户端从返回的流中读取,直到没有更多消息为止。客户端流式RPC,其中客户端写入一系列消息并将它们发送到服务端,再次使用提供的流。一旦客户端完成了消息的写入,它会等待服务端读取所有消息并返回其响应。

ldxxxxll的博客 1478

【从零开始学习Go语言】一.初识Go语言

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。

一只特立独行的兔先森 1万+

非零基础自学Golang 第14章 反射 14.3 对结构体的反射操作

非零基础自学Golang 第14章 反射 14.3 对结构体的反射操作

代码改变世界 963
上一篇: 从零开始学GO ---- Go中函数的方方面面
下一篇: 从零开始学GO ---- 错误处理
coding丁
博客等级 码龄9年 383粉丝 147原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值