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]

到此这篇关于Go语言学习之结构体和方法使用详解的文章就介绍到这了,更多相关Go语言结构体 方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go语言结构体定义和使用方法

    本文实例讲述了Go语言结构体定义和使用方法.分享给大家供大家参考.具体分析如下: 一个结构体(struct)就是一个字段的集合. (而 type 定义跟其字面意思相符.) 复制代码 代码如下: package main import "fmt" type Vertex struct {     X int     Y int } func main() {     fmt.Println(Vertex{1, 2}) } 结构体字段使用点号来访问. 复制代码 代码如下: package

  • Go语言基础语法之结构体及方法详解

    结构体类型可以用来保存不同类型的数据,也可以通过方法的形式来声明它的行为.本文将介绍go语言中的结构体和方法,以及"继承"的实现方法. 结构体类型 结构体类型(struct)在go语言中具有重要地位,它是实现go语言面向对象编程的重要工具.go语言中没有类的概念,可以使用结构体实现类似的功能,传统的OOP(Object-Oriented Programming)思想中的继承在go中可以通过嵌入字段的方式实现. 结构体的声明与定义: // 使用关键字 type 和 struct 定义名字

  • Go语言指针访问结构体的方法

    本文实例讲述了Go语言指针访问结构体的方法.分享给大家供大家参考.具体分析如下: Go有指针,但是没有指针运算. 结构体字段可以通过结构体指针来访问.通过指针间接的访问是透明的. 复制代码 代码如下: package main import "fmt" type Vertex struct {     X int     Y int } func main() {     p := Vertex{1, 2}     q := &p     q.X = 1e9     fmt.P

  • Go语言之结构体与方法

    目录 一.结构体 1.结构体的定义与使用 2.定义并赋初值 3.匿名结构体(只使用一次,没有名字) 4.结构体的零值 5.结构体的指针 6.匿名字段(字段没有名字,只有类型) 7.嵌套结构体(结构体中套结构体) 8.字段提升 9.结构体相等性 二.方法 1.方法的定义和使用 2.有了函数为啥还需要方法? 3.指针接收器与值接收器 5.匿名字段的方法(方法提升) 6.在方法中使用值接收器 与 在函数中使用值参数 7.在方法中使用指针接收器 与 在函数中使用指针参数 8.非结构体上绑定方法 一.结构

  • 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不属于同一类型,需要转换 fm

  • C语言程序中结构体的内存对齐详解

    目录 一.为什么存在内存对齐 二.结构体的内存对齐四规则 三.举例 一.为什么存在内存对齐 1.平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的:某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常. 2. 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐. 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问:而对齐的内存访问仅需要一次访问. 总的来说结构体的内存对齐是拿空间来换取时间的做法. 二.结构体的内存对齐四规则 默认情况:默认的对

  • C语言热门考点结构体与内存对齐详解

    目录 一.引例 1.结构体的第一个成员永远放在结构体起始位置偏移量为0的位置 2.从第二个成员开始,总是放在偏移量为一个对齐数的整数处,对齐数=编译器默认的对齐数和变量自身大小的较小值 3.结构体的总大小必须是各个成员的对齐数中最大的那个对齐数的整数倍 二.小试牛刀 三.嵌套结构体的特殊情况 四.关于为什么存在内存对齐 1.平台原因(移植原因): 2.性能原因: 总结 一.引例 到底什么是结构体内存对齐,我们用一段代码来介绍一下 struct S1 { char c1;//1字节 int a;/

  • Go语言学习函数+结构体+方法+接口

    目录 1. 函数 1.1 函数返回值 同一种类型返回值 带变量名的返回值 函数中的参数传递 函数变量 1.2 匿名函数——没有函数名字的函数 在定义时调用匿名函数 将匿名函数赋值给变量 匿名函数用作回调函数 可变参数——参数数量不固定的函数形式 1.3 闭包 1.4 defer语句 处理运行时发生的错误 1.5 宕机恢复(recover)——防止程序崩溃 2. 结构体 2.1 定义与给结构体赋值 3. 方法 3.1 结构体方法 3.2 接收器 指针接收器 非指针类型接收器 4. 接口 4.1 声

  • go语言结构体指针操作示例详解

    目录 指针 go指针操作 不能操作不合法指向 new函数 指针做函数的参数 数组指针 结构体指针变量 结构体成员普通变量 结构体成员指针变量 结构体比较和赋值 结构体作为函数参数 指针 指针是代表某个内存地址的值.内存地址储存另一个变量的值. 指针(地址),一旦定义了不可改变,指针指向的值可以改变 go指针操作 1.默认值nil,没有NULL常量 2.操作符“&”取变量地址,“*“通过指针(地址)访问目标对象(指向值) 3.不支持指针运算,不支持“->”(箭头)运算符,直接用“.”访问目标成

  • C++ 结构体初始化与赋值详解

    目录 1.结构体初始化 2.结构体赋值 参考文献 1.结构体初始化 结构体是常用的自定义构造类型,是一种很常见的数据打包方法.结构体对象的初始化有多种方式,分为顺序初始化.指定初始化.构造函数初始化.假如有如下结构体. struct A { int b; int c; }; (1)顺序初始化因为书写起来较为简约,是我们最常用的初始化方式,但相对于指定初始化,无法变更数据成员初始化顺序,灵活性较差,而且表现形式不直观,不能一眼看出 struct 各个数据成员的值. A a = {1, 2}; (2

  • Go结构体的基本使用详解

    目录 定义 实例化 匿名结构体 空结构体 构造函数 方法与接收者 匿名字段 实现面向对象的“继承”特性 标签tag 结构体与JSON系列化 本文主要介绍Go的结构体类型的基本使用,快速上车 定义 结构体,是一种自定义的数据类型,由多个数据类型组合而成.用于描述一类事物相关属性. 定义方式: type 类型名 struct { 字段名 字段类型 - } //示例: type Animal struct { Name string Age int } 实例化 结构体和结构体指针,两者的实例化有所区别

  • Go语言学习之函数的定义与使用详解

    目录 1.函数定义 2.多值返回 3.引用传递 4.函数作为实参使用 5.匿名函数 1.函数定义 函数的定义和java一样,使用{}进行包裹,并且要明确入参类型以及返回类型. 样例代码如下: func min(num1, num2 int) int { if num1 <= num2 { return num1 } else { return num2 } } func main() { fmt.Printf("max = %d\n", min(10, 12)) } 执行结果 m

  • C语言 结构体(Struct)详解及示例代码

    前面的教程中我们讲解了数组(Array),它是一组具有相同类型的数据的集合.但在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,年龄为整数,所在的学习小组为字符,成绩为小数,因为数据类型不同,显然不能用一个数组来存放. 在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据.结构体的定义形式为: struct 结构体名{     结构体所包含的变量或数组 }; 结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可

随机推荐