Go 语言 结构体和方法

简介: 1. 结构体别名定义2. 工厂模式3. Tag 原信息4. 匿名字段5. 方法

1. 结构体别名定义


变量别名定义


package main
import "fmt"
type integer int
func main() {
  //类型别名定义
  var i integer = 1000
  fmt.Printf("值: %d, 类型: %T\n", i, i)
  var j int = 100
  j = int(i)      //j和i不属于同一类型,需要转换
  fmt.Println(j)
}
//输出结果如下
值: 1000, 类型: main.integer
1000


结构体别名定义


package main
import "fmt"
//创建结构体Student
type Student struct {
  Number int
}
//结构体定义别名
type Stu Student
func main() {
  //声明Student类型结构体
  var a Student
  a = Student{30}
  //声明Stu类型结构体
  var b Stu
  b = Stu{20}
  //强转类型后才能进行赋值
  a = Student(b)
  fmt.Printf("a = %d,类型: %T\n", a, a)
  b = Stu(a)
  fmt.Printf("b = %d,类型: %T\n", b, b)
}
//输出结果如下
a = {20},类型: main.Student
b = {20},类型: main.Stu

2. 工厂模式


Go中所谓的工厂模式其实就是:


包内一个不可直接实例的结构体(结构体名称首字母小写),包外不可直接实例,那么为了解决这个问题,就写一个包外可调用的函数,通过这个函数实现返回结构体对象。

package main
import "fmt"
type Student struct {
  Name string
  Age  int
}
func main() {
  //初始化
  stu1 := new(Student)
  fmt.Println(stu1)
  //工厂模式处理
  stu2 := NewStudent("张三", 18)
  fmt.Println(stu2)
}
//工厂模式
func NewStudent(name string, age int) *Student {
  return &Student{
    Name: name,
    Age:  age,
  }
}
//输出结果如下
&{ 0}
&{张三 18}

总结

make 用来创建mapslicechannel

new 用来创建值类型


3. Tag 原信息


  • 在和其他语言进行对接交互时使用JSON格式,有些语言格式大小写规范比较严格,为了使Go语言和其他语言对接数据传输,所以使用Tag原信息进行解决
  • 通俗的来说就相当于是一个充电的转接口

示例

package main
import (
  "encoding/json"
  "fmt"
)
type Student struct {
  Name  string
  Age   int
  Score float32
}
func main() {
  //初始化
  var stu = new(Student)
  stu.Name = "stu"
  stu.Age = 20
  stu.Score = 88
  //使用Json处理结构体,转换成字节数组
  data, err := json.Marshal(stu)
  if err != nil {
    fmt.Println("错误提示:", err)
    return
  }
  fmt.Println(data)       //字节数组形式输出
  fmt.Println(string(data))   //转换成字符串输出
}
//输出结果如下
[123 34 78 97 109 101 34 58 34 115 116 117 34 44 34 65 103 101 34 58 50 48 44 34 83 99 111 114 101 34 58 56 56 125]
{"Name":"stu","Age":20,"Score":88}


JSON格式化字段名


package main
import (
  "encoding/json"
  "fmt"
)
type Student struct {
  //json打包时字段名
  Name  string  `json:"stu_name"`
  Age   int     `json:"stu_age"`
  Score float32 `json:"stu_score"`
}
func main() {
  //初始化
  var stu = new(Student)
  stu.Name = "stu"
  stu.Age = 20
  stu.Score = 88
  //使用Json处理结构体,转换成字节数组
  data, err := json.Marshal(stu)
  if err != nil {
    fmt.Println("错误提示:", err)
    return
  }
  fmt.Println(data)
  fmt.Println(string(data))
}
//输出结果如下
[123 34 115 116 117 95 110 97 109 101 34 58 34 115 116 117 34 44 34 115 116 117 95 97 103 101 34 58 50 48 44 34 115 116 117 95 115 99 111 114 101 34 58 56 56 125]
{"stu_name":"stu","stu_age":20,"stu_score":88}


4. 匿名字段


结构体中的字段(属性)没有名称,称之为匿名字段

示例


package main
import "fmt"
type Cart struct {
  name  string
  color string
}
type Train struct {
  //匿名字段
  Cart //实现继承
  int  //数据类型定义,仅能存在一次,两个int则会冲突
}
func main() {
  //初始化赋值
  var t Train   
  t.name = "train"
  t.color = "red"
  t.int = 10    //直接调用数据类型赋值
  fmt.Println(t)
}
//输出结果如下
{{train red} 10}


双引用结构体,多继承(继承的两个结构体中定义相同属性)


package main
import "fmt"
//父结构体
type Cart struct {
  name  string
  color string
}
//父结构体
type Box struct {
  color string
}
//子结构体
type Train struct {
  //匿名字段
  Cart //实现继承
  Box
  int //数据类型定义,仅能存在一次,两个int则会冲突
}
func main() {
  //初始化赋值
  var t Train
  t.name = "train"
  t.Cart.color = "red"
  t.Box.color = "blue"
  t.int = 10 //直接调用数据类型赋值
  fmt.Println(t)
}
//输出结果如下
{{train red} {blue} 10}
package main
import "fmt"
//父结构体
type Cart struct {
  name  string
  color string
}
//父结构体
type Box struct {
  color string
}
//子结构体
type Train struct {
  //匿名字段
  Cart //实现继承
  Box
  int   //数据类型定义,仅能存在一次,两个int则会冲突
  color string
}
func main() {
  //初始化赋值
  var t Train
  t.name = "train"
  t.Cart.color = "red" //Cart的属性
  t.Box.color = "blue" //Box的属性
  t.color = "yellow"   //train自身属性
  t.int = 10           //直接调用数据类型赋值
  fmt.Println(t)
}


5. 方法


  • Go 中的方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是 struct
  • 语法格式如下
func (recevier type) methodName(参数列表)(返回值){}
recevier type     特定类型,如指针、别名,结构体 
methodName        方法名
  • 示例
package main
import "fmt"
//定义结构体
type Student struct {
  Name string
  Age  int
}
//定义方法
func (s Student) init(name string, age int) Student {
  s.Name = name
  s.Age = age
  return s
}
func main() {
  var stu Student
  s := stu.init("zhangsan", 18)
  fmt.Printf("s: %v\n", s)
}
//输出结果
s: {zhangsan 18}


定义返回方法是否会把初始化的值给返回?


package main
import "fmt"
//定义结构体
type Student struct {
  Name  string
  Age   int
  Score float32
}
//初始化方法
func (s *Student) init(name string, age int, score float32) {
  s.Name = name
  s.Age = age
  s.Score = score
  fmt.Println("初始化完成")
}
//返回结构体
func (s *Student) get() Student {
  return *s
}
func main() {
  var stu Student
  //定义值
  stu.init("zhangsan", 18, 90)
  //返回值
  stu1 := stu.get()
  fmt.Println(stu1)
}
//输出结果如下
初始化完成
{zhangsan 18 90}


传统数据类型自定义方法,做数据类型转换


package main
import "fmt"
//别名类型
type integer int
//传统数据类型自定义方法
func (p integer) convert() string {
  return fmt.Sprintf("%d", p)
}
func main() {
  var i integer
  i = 100
  s := i.convert()
  fmt.Printf("类型:%T,值:%s\n", s, s)
}
//输出结果如下
类型:string,值:100


指针传入和值传入的区别

值传入不会对数值进行改变,指针传入才可以改变数值


package main
import "fmt"
type integer int
//传统数据类型自定义方法
func (p integer) convert() string {
  return fmt.Sprintf("%d", p)
}
//方法传指针进行数据同步修改
func (p *integer) set(b integer) {
  *p = b
}
func main() {
  var i integer
  i = 100
  s := i.convert()
  fmt.Printf("类型: %T ,值: %s\n", s, s)
  fmt.Printf("类型: %T ,值: %d\n", i, i)
  i.set(200)
  fmt.Printf("i: %v\n", i)
}
//输出结果如下
类型: string ,值: 100
类型: main.integer ,值: 100
i: 200

方法继承,组合(匿名字段是组合的特殊形式)

package main
import "fmt"
//父结构体
type Car struct {
  weight int
  name   string
}
//父方法
func (c *Car) Run() {
  fmt.Println("Running")
}
//子结构体Bike
type Bike struct {
  //组合(有名字)
  c     Car
  wheel int
}
//子结构体Train
type Train struct {
  //匿名
  Car
  wheel int
}
func main() {
  var bike Bike
  bike.c.name = "bike"
  bike.c.weight = 500
  bike.wheel = 2
  var train Train
  train.name = "train"
  train.weight = 140000
  train.wheel = 8
  fmt.Println(bike)
  //方法继承,调用父结构体方法
  bike.c.Run()
  fmt.Println(train)
  //方法继承
  train.Run()
}
//输出结果如下
{{500 bike} 2}
Running
{{140000 train} 8}
Running
package main
import "fmt"
//父结构体
type Cart struct {
  weight int
  Color  string
}
//父方法
func (c Cart) Run() {
  fmt.Println("Running")
}
//子结构体train
type Train struct {
  Cart
  wheel int
}
//子结构体方法
func (t Train) String() string {
  str := fmt.Sprintf("color:[%s],weight:[%d],wheel:[%d]\n", t.Color, t.weight, t.wheel)
  return str
}
func main() {
  var train Train
  train.Color = "red"
  train.weight = 14000
  train.wheel = 8
  fmt.Println(train)
  train.Run()
  fmt.Printf("%s\n", train)
}
//输出结果如下
color:[red],weight:[14000],wheel:[8]
Running
color:[red],weight:[14000],wheel:[8]
目录
打赏
0
0
0
0
8
分享
相关文章
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
|
2月前
|
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
Go 语言入门指南:切片
eino — 基于go语言的大模型应用开发框架(二)
本文介绍了如何使用Eino框架实现一个基本的LLM(大语言模型)应用。Eino中的`ChatModel`接口提供了与不同大模型服务(如OpenAI、Ollama等)交互的统一方式,支持生成完整响应、流式响应和绑定工具等功能。`Generate`方法用于生成完整的模型响应,`Stream`方法以流式方式返回结果,`BindTools`方法为模型绑定工具。此外,还介绍了通过`Option`模式配置模型参数及模板功能,支持基于前端和用户自定义的角色及Prompt。目前主要聚焦于`ChatModel`的`Generate`方法,后续将继续深入学习。
350 7
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
38 3
eino — 基于go语言的大模型应用开发框架(一)
Eino 是一个受开源社区优秀LLM应用开发框架(如LangChain和LlamaIndex)启发的Go语言框架,强调简洁性、可扩展性和可靠性。它提供了易于复用的组件、强大的编排框架、简洁明了的API、最佳实践集合及实用的DevOps工具,支持快速构建和部署LLM应用。Eino不仅兼容多种模型库(如OpenAI、Ollama、Ark),还提供详细的官方文档和活跃的社区支持,便于开发者上手使用。
301 8
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
阿里双十一背后的Go语言实践:百万QPS网关的设计与实现
解析阿里核心网关如何利用Go协程池、RingBuffer、零拷贝技术支撑亿级流量。 重点分享: ① 如何用gRPC拦截器实现熔断限流; ② Sync.Map在高并发读写中的取舍。
基于 Go 语言的公司内网管理软件哈希表算法深度解析与研究
在数字化办公中,公司内网管理软件通过哈希表算法保障信息安全与高效管理。哈希表基于键值对存储和查找,如用户登录验证、设备信息管理和文件权限控制等场景,Go语言实现的哈希表能快速验证用户信息,提升管理效率,确保网络稳定运行。
34 0
Go: struct 结构体类型和指针【学习笔记记录】
本文是Go语言中struct结构体类型和指针的学习笔记,包括结构体的定义、成员访问、使用匿名字段,以及指针变量的声明使用、指针数组定义使用和函数传参修改值的方法。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等