#### 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. 【LeetCode】1415. 长度为 n 的开心字符串中字典序第 k 小的字符串 The k-th Lexicographical String of All Happy Strings of Le

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetcod ...

  2. 【LeetCode】954. Array of Doubled Pairs 解题报告(Python)

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

  3. 【LeetCode】290. Word Pattern 解题报告(Python)

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

  4. 【LeetCode】636. Exclusive Time of Functions 解题报告(Python)

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

  5. 牛客练习赛44 C:小y的质数

    链接:https://ac.nowcoder.com/acm/contest/634/C?tdsourcetag=s_pcqq_aiomsg 来源:牛客网 题目描述 给出一个区间\([L,R]\),求 ...

  6. 小试国产开源HTAP分布式NewSQL数据库TiDB-v5.3.0

    概述 定义 TiDB官网 https://pingcap.com/zh/ 最新版本为5.3.0 TiDB GitHub源码 https://github.com/pingcap/tidb TiDB是由 ...

  7. Adversarially Robust Generalization Requires More Data

    目录 概 主要内容 高斯模型 upper bound lower bound 伯努利模型 upper bound lower bound Schmidt L, Santurkar S, Tsipras ...

  8. 编写Java程序,根据提供的 IP 地址,获取主机名称和域名

    查看本章节 查看作业目录 需求说明: 根据提供的 IP 地址,获取主机名称和域名 实现思路: 创建 GetHostNameByIpAddress 类,在main方法中声明 String 类型的变量 i ...

  9. MongoDB 安装及制作成windows服务

    下载:  注:直接使用浏览器下载速度很慢,建议使用其他下载软件下载(比如:迅雷) 官网下载地址: https://fastdl.mongodb.org/win32/mongodb-win32-x86_ ...

  10. Python_对excel表格读写-openpyxl、xlrd&xlwt

    openpyxl 和 xlrd&xlwt 都能对excel进行读写,但是它们读写的格式不同,openpyxl 只能读写 xlsx格式的excel,xlrd&xlwt 只能读写 xls格 ...