#### Go 面向对象之结构体
最近有四天没更新公众号,有一些事情耽误了,生活就是这样,总会一些事情让人措不及防;
***山浓水浅,坐看流年***

1. Go 也支持面向对象编程(OOP) 但是它和传统的面向对象编程还是有一些区别,并不是纯粹的面向对象编程;
2. Go 中没有类(class), Go 中struct 和其它编程语言中的类有同等地位,所以我们可以理解Go 是基于struct 来实现OOP;
3. Go 面向对象很简洁,没有传统OOP 的继承,方法重载,构造函数等等;
4. Go 面向对象仍有继承,封装,多态的特性,只是它的实现与传统的OOP语言不同;
##### 结构体与结构体变量(实例/对象)的关系图

 
---
说明:
1. 将一类事物的特性提取出来(比如猫类),形成一个新的数据类型就是一个结构体;
2. 通过这个结构体,可以创建多个变量(实例/对象);
3. 事物可以是猫类,也可以是其它的类...;
案例:
package main

import "fmt"

// 定义一个结构体,类似于类
// 将Cat 的各个字段/属性,放入到结构体中
type Cat struct {
Name string
Age uint
Color string
Hobby string
}
func main(){
// 声明一个Cat 变量,也就是实例
var a1 Cat
a1.Name = "小花"
a1.Age = 2
a1.Color = "black"
a1.Hobby = "老鼠"
fmt.Println(a1)
fmt.Printf("name=%s\n",a1.Name)
fmt.Printf("age=%d\n",a1.Age)
fmt.Printf("color=%s\n",a1.Color)
fmt.Printf("hobby=%s\n",a1.Hobby)
}

  


---
结构体与结构体变量(实例)的区别
1. 结构体是自定义的数据类型,代表一类事物;
2. 结构体变量是具体的,实际的,代表一个具体的变量;
---
##### 结构体变量在内存中的布局

  

##### 如何声明结构体
基本语法:
type 结构体名称 struct {
field1 type
field2 type
...
}
例如:
typt Person struct {
Name string
Age int
Class string
}
##### 字段属性
字段是结构体的组成部分,一般是基本数据类型,数组,同时也可以是引用类型;
注意事项:
1. 字段声明语法同变量一样: 字段名 字段类型
2. 在创建一个结构体变量后,如果没有给字段赋值,每个字段都对应一个默认值,引用类型默认值为nil;
3. 不同结构体变量的字段是独立的,互不影响: 结构体是值类型;
package main

import "fmt"

// 如果结构体里的字段是引用类型的: slice map channel;
// 在使用前需要make分配内存才能使用;
type Person struct {
Name string
Age int
Hobby [3]string
ptr *string
slice []int
Parents map[string]string
}
type Cat struct {
Name string
Age int
}
func main(){
var a1 Person
fmt.Println(a1) //{0 [] nil [] map[]}
if a1.ptr == nil {
fmt.Println("ptr is nil")
}
if a1.slice == nil {
fmt.Println("slice is nil")
}
if a1.Parents == nil {
fmt.Println("parents is nil")
}
// 结构体字段是引用类型的话,使用前需要make
a1.slice = make([]int,10)
a1.slice[0] = 1
a1.slice[1] = 2
a1.slice[2] = 3
a1.Parents = make(map[string]string)
a1.Parents["name"] = "aaaa"
a1.Parents["friendly"] = "father"
fmt.Println(a1) // { 0 [ ] <nil> [1 2 3 0 0 0 0 0 0 0] map[friendly:father name:aaaa]}
// 不同结构体变量间互不影响
var c1 Cat
var c2 Cat
c1.Name = "c1"
c2.Name = "c2"
c1.Age = 1
c2.Age = 2
fmt.Println(c1,c2) //{c1 1} {c2 2}
}

  


---
##### 创建结构变量和访问结构体字段
package main

import "fmt"

type Cat struct {
Name string
Age int
}
func main(){
// 方式1: 先声明,再赋值
var c1 Cat
c1.Name = "c1"
c1.Age = 1
fmt.Println(c1) //{c1 1}
// 方式2: 字面量方式
var c2 Cat = Cat{"c2",2}
fmt.Println(c2) //{c2 2}
// 方式3: 类型推导方式
c3 := Cat{"c3",3}
fmt.Println(c3) //{c3 3}
// 方式4: new 方式
var c4 *Cat = new(Cat)
c4.Name = "c4"
c4.Age = 4
fmt.Println(*c4)
// 方式5: &{} 方式
var c5 *Cat = &Cat{}
c5.Name = "c5"
c5.Age = 5
fmt.Println(*c5)
// 方式4,方式5 返回的都是结构体的指针类型
}

  


1. 第4,5 种方式返回的是***结构体指针***;
2. 结构体指针访问字段的标准方式应该是:(*结构体指针).字段名, 如:(*c4).Name = "c4";
3. Go 做了简化,支持***结构体指针.字段名***,如:c4.Name = "c4",Go 编译器底层自动处理了;
---
##### 结构体使用注意事项
1. 结构体中所有的字段在内存中是连续的;
2. 结构体是用户自定义的类型,在和其它类型转换时需要有完全相同的字段(名称,个数,类型);
3. 结构体进行type 定义,Go 认为是新的数据类型,可以和基本数据类型进行强转;
4. 结构体每个字段上可以写tag,tag 可以通过反射机制获取,常用的场景是序列化和反序列化;
package main

import (
"encoding/json"
"fmt"
) type Person struct {
Name string
Age int
Hobby string
}
type Student struct {
Name string
Age int
Hobby string
}
type Cat struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main(){
var p1 Person
p1.Name = "p1"
p1.Age = 22
p1.Hobby = "run"
// 结构体变量的地址
fmt.Printf("p1 address: %p\n",&p1)
fmt.Printf("p1.Name address: %p\n",&p1.Name) // 0xc0000562d0
fmt.Printf("p1.Age address: %p\n",&p1.Age) // 0xc0000562e0 , 一个string 是16 字节
fmt.Printf("p1.Hobby address: %p\n",&p1.Hobby)//0xc0000562e8 , 一个int 在64 位系统中为8字节
// 类型之间强转
var s1 Student
s1 = Student(p1)
fmt.Println(s1)
fmt.Printf("s1 type is %T\n",s1) // Student
// struct tag
var c1 Cat
c1.Name = "小花"
c1.Age = 12
jsonStr,err := json.Marshal(c1)
if err != nil {
fmt.Println(err)
}
// 输出的是结构体中tag 定义的名称
fmt.Println(string(jsonStr)) // {"name":"小花","age":12}
}

  个人微信公众号上有最新内容,欢迎关注交流学习

Go 面向对象之结构体的更多相关文章

  1. Go语言基础之结构体

    Go语言基础之结构体 Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念.Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性. 类型别名和自定义类型 自定义类型 在G ...

  2. (10)Go结构体struct

    结构体 Go语言中的基础数据类型可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,Go语言提供了一种自定义数据类型,可以封装多个 ...

  3. GO学习-(13) Go语言基础之结构体

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

  4. Golang通脉之结构体

    Go语言中的基础数据类型可以表示一些事物的基本属性,但是要表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,Go语言提供了一种自定义数据类型,可以封装多个基本数据类型, ...

  5. c语言里用结构体和指针函数实现面向对象思想

    一.基础研究 观察如下两个程序a.c和b.c: A.c: B.c: 这两个程序都是要实现在屏幕上第10行40列打印一个绿色的字符c: 这两个程序的数据组织方式是一样的,都是使用结构体,而且对共性和个性 ...

  6. C语言:使用结构体和指针函数实现面向对象思想(OO编程)

    原文:https://www.linuxidc.com/Linux/2016-12/138789.htm 有关:<C语言:过年回家 发现只有我没有对象> 一.基础研究 观察如下两个程序a. ...

  7. Golang面向对象编程-struct(结构体)

    Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...

  8. 《objective-c基础教程》学习笔记(三)—— 从结构体到面向对象

    一听标题,感觉十分的抽象.面向对象就是(Object-Oriented Programming)的首字母缩写:OOP,是当今最主流的编程方法. 那么,面向对象编程具体有什么好处呢.是如何来实现呢?通过 ...

  9. 用C结构体来实现面向对象编程,ti xDAIS标准算法就这么搞的(1)

    用C结构体来实现面向对象编程,ti xDAIS标准算法就这么搞的. 测试代码如下: #include <stdio.h> #include <stdlib.h> #includ ...

随机推荐

  1. JAVAWEB项目报"xxx响应头缺失“漏洞处理方案

    新增一个拦截器,在拦截器doFilter()方法增加以下代码 public void doFilter(ServletRequest request, ServletResponse response ...

  2. 【LeetCode】389. Find the Difference 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:字典统计次数 方法二:异或 方法三:排序 日 ...

  3. 【LeetCode】1004. Max Consecutive Ones III 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 虫取法/双指针 日期 题目地址:https://le ...

  4. 【LeetCode】58. Length of Last Word 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 库函数 双指针 单指针 日期 题目地址:https: ...

  5. 论文翻译:2019_Deep Neural Network Based Regression Approach for A coustic Echo Cancellation

    论文地址:https://dl.acm.org/doi/abs/10.1145/3330393.3330399 基于深度神经网络的回声消除回归方法 摘要 声学回声消除器(AEC)的目的是消除近端传声器 ...

  6. 第十个知识点:RSA和强RSA问题有什么区别?

    第十个知识点:RSA和强RSA问题有什么区别 这个密码学52件事数学知识的第一篇,也是整个系列的第10篇.这篇介绍了RSA问题和Strong-RSA问题,指出了这两种问题的不同之处. 密码学严重依赖于 ...

  7. Kronecker Products and Stack Operator

    目录 定义 Stack Operator Kronecker Product 性质 Stack Operator Kronecker Product 半线性 Whitcomb L. Notes on ...

  8. oracle中connect by prior的使用

    作用 connect by主要用于父子,祖孙,上下级等层级关系的查询 语法 { CONNECT BY [ NOCYCLE ] condition [AND condition]... [ START ...

  9. vue从入门到精通之【vuex】(七)

    vue从入门到精通之[vuex](七) vuex一个公用的大仓库,Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架. Vuex 实现了一个单向数据流,在全局拥有一个 state 存放数据, ...

  10. 编写Java程序_定义两个方法,实现奇数偶数的判断,并计算和(有参数有返回值方法)

    需求说明: 定义两个方法,在控制台输入一个数字,这两个方法可以求出1到该数字之间所有偶数之和.奇数之和,并将对应结果和返回.在main方法中调用该方法,并在控制台打印出结果.(有参数有返回值方法) 运 ...