4.1.结构体 结构体:讲一个或多个变量组合到一起形成新的类型,这个类型就是结构体,结构体是值类型 定义结构体和赋值 //Learn_Go/main.go package main import "fmt //{jack 12} //第三种 peo.Name = "alice" peo.Age = 25 fmt.Println(peo) //{alice 25} } 4.2.结构体指针 由于结构体是值类型,在方法传递时希望传递结构体地址,可以使用结构体指针完成 可以结合new()函数创建结构体指针 //Learn_Go/main.go package main import "fmt Jack" fmt.Println(peo, peo2) //&{Jack 22} &{Jack 22} } 4.3.方法 方法和函数语法比较像,区别是函数属于包,通过包调用函数,而方法属于结构体 ,通过结构体变量调用 默认是函数,隶属于包,所以需要添加标识,告诉编译器这个方法属于哪个结构体 (1)创建方法 //Learn_Go/main.go package main import "fmt
介绍匿名结构体 在前面的示例中,使用了一个没有名称的结构体,我们通常称之为匿名结构体。它允许我们在需要结构体但不需要重复使用该结构类型的场景中快速定义和初始化结构。 2. 优势分析 简洁性 代码简洁:匿名结构体允许我们在定义变量的同时声明其类型,这减少了代码量并提高了可读性。 减少命名负担:对于只使用一次的小型结构体,无需费心命名。 劣势讨论 可维护性 难以重用:如果相同的数据结构在代码中多处使用,每次都需要重新声明,这会增加维护成本。 可读性问题:对于复杂的结构体或者在大型项目中,使用匿名结构体可能会使代码难以理解和维护。 性能考虑 性能影响:虽然通常不显著,但在某些性能敏感的应用中,频繁创建匿名结构体可能会产生不必要的开销。 4. 使用场景 适合使用 临时数据处理:处理临时数据或构造一次性响应时非常方便。 通过权衡其优势和劣势,我们可以在合适的时候使用匿名结构体来提高自己的编码效率。 现在,可以根据这篇文章的内容,考虑是否在我们的Go项目中使用匿名结构体,以及如何高效地使用它们。
一句话总结:匿名结构体=临时数据打包神器,用完即走,不占编制!啥是匿名结构体? 普通结构体像"正式员工",得先注册类型:展开代码语言:GoAI代码解释typeCarstruct{MakestringModelstringYearint}camry:=Car{Make:"Toyota ",Model:"Camry",Year:2020}匿名结构体? 没门)✅减少类型污染,代码轻量❌无法复用,复制粘贴警告⚠️✅测试/配置场景神器❌字段多了可读性暴跌我的原则:核心业务用命名结构体,临时胶水代码用匿名结构体——就像厨房:主菜用专业厨具,拌个沙拉用一次性碗 最后唠两句匿名结构体不是"银弹",但绝对是工具包里的"瑞士军刀"。用对了场景,代码清爽如新;滥用?恭喜你,喜提"天书代码"成就。
下面我先从普通结构体说起,带大家看看什么情形下用匿名结构体会带来编码效率的提升。 具名结构体 具名结构体就是平时用的普通结构体。 ", model: "taurus", mileage: 200000, } 匿名结构体 匿名结构体顾名思义就是没有名字的结构体,通常只用于在代码中仅使用一次的结构类型,比如 func 如果一个结构体初始化后只被使用一次,那么使用匿名结构体就会很方便,不用在程序的package中定义太多的结构体类型,比如在解析接口的响应到结构体后,就可以使用匿名结构体 用于解析接口响应 func createCarHandler 比如程序拿到接口响应后需要按业务规则加工下才能创建DTO实例这种情况,就很适合用匿名结构体先解析响应。 比用map更健壮 这里再说一点使用匿名结构体的好处。 用于定义项目约定的公共字段 除了上面这种结构体初始化后只使用一次的情况,在项目中定义各个接口的返回或者是DTO时,有的公共字段使用匿名结构体声明类型也很方便。
1.DEMO 使用匿名类型: static void Main() { var someType = new { Name = "乱舞春秋", Age = 22, Sex = "男" }; 我们都知道Console.WriteLine会去调用参数的ToString方法,那么可以肯定匿名类型someType重写了ToString方法。 那么如果我再上面的基础上再加上一个匿名类型,只不过把属性循序换下,如下: static void Main() { var someType = new { Name = "乱舞春秋", Age 从匿名类型重写ToString方法就可以理解到编译器为什么会这么做了[...]。 如果属性的顺序和个数及名字都相同,那么编译器就会只生成一份。 匿名类型直接继承自System.Object,其成员是根据初始化器推断而来的读写属性,一般会结合var关键字来使用。
结构体 定义的基本格式: struct Name { // 一堆定义代码 }; 例子: struct studentInfo { int id; char gender; char name[20]; char major[20]; }Alice, stu[1000]; studentInfo就是结构体的名字,Alice就是结构体变量,stu[1000]就是结构体数组 结构体里面不能够出现自身的数据类型(不然会循环定义)。 结构体的元素的访问方法之类的基本的知识点就不提了,这些网上都有。这里想记一下的主要是构造函数。 构造函数就是用来初始化结构体的函数,直接定义在结构体内。构造函数不需要写返回类型,且函数名和结构体名相同。 gender = _gender; } } 用法: studentInfostu = studentInfo(10086, 'M'); 注意,定义了构造函数则不能够不经过初始化就定义结构体变量
漫天飞舞的匿名字段,是不是像golang大神特有的标签。运行一下,没问题,符合预期,完美。 故障原因 查看代码提交记录,一处改动进入视野,最近新增了一个查询数据库的功能,与OperationQueryCKV类似的,新增定义了一个OperationQuerySQL,只是新定义了结构 估计就是两个匿名L5,把值搞没了。试着跑一下样例代码。 根本原因应该是匿名变量导致的json字段key重复。 暂时也不知道好的办法,建议是不用或者少用匿名字段,如果需要使用匿名字段,每项都定义不同的`json:"_key_“`。
1 #include <stdio.h> 2 union 3 { 4 int i; 5 char x[2]; 6 }a; 7 8 void main() 共用体和结构体的区别在于:结构体的每个域都有它自己的存储空间;共用体所有域共用一个存储空间。所以共用体每一时刻只有一个域的值有意义。 结构体的大小为所有域占用空间的总和;共用体的大小为占用空间最大的域的大小
结构体的声明 结构的基础知识 结构是一些值的集合,这些值称为成员变量。 = {"zhangsan", 20};//初始化 struct Node { int data; struct Point p; struct Node* next; }n1 = {10, {4,5 结构体指针访问指向变量的成员有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。 return 0; } 结构体传参 struct S { int data[1000]; int num; }; struct S s = {{1,2,3,4}, 1000}; //结构体传参 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。 结论: 结构体传参的时候,要传结构体的地址
结构体 结构体的作用 数组:具有相同类型的数据的集合 结构体:存储不同类型的数据项 单一的数据类型无法满足特定的需求,数据类型的集合体:结构体 出现了 结构体的定义和使用 结构体的定义方式 结构体是一种自定义数据类型 struct用来定义一个类型 结构体的定义: 1struct 结构体名字 2{ 3 //成员变量 4}; 定义结构体后再定义变量 1//例1: 2struct stu 3{ 4 int id //定义变量 引用结构体变量中的成员 点运算符访问结构体的成员变量 . 1//对例2的结构体变量进行访问 2stu1.id=1001; 3strcpy(stu1.name,"小明同学"); 4 5arr 内存对齐 结构体变量大小 >= 结构体所有成员变量大小 结构体总大小为最大对齐数的整数倍 1#include<stdio.h> 2typedef struct test 3{ 4 int 该结构体最大对齐数为 int 也就是4个字节大小 ,结构体的大小就是4的整数倍 ?
(如 int ) 函数参数是什么类型就传什么类型 /* 函数功能:定义一个结构体,在另一个函数中打印结构体成员的值; 函数形参为结构体变量的函数使用void qq(struct book cc); */ -即struct book cc和struct book one; 问一个问题如何把一个结构体的变量的成员的信息copy到另一个结构体变量? one; //定义一个结构体名为book的结构体变量one struct book cc; //定义一个结构体名为book的结构体变量cc one.cose=25; one.name struct book shu[20]; //20本书 /* 函数功能:结构体变量为数组的结构体 */ /* 函数功能:结构体变量为数组的结构体 */ #include"stdio.h" struct price=1; //书0的价格 shu[1].price=2; //书1的价格 shu[2].price=3; //书2的价格 shu[3].price=4;
结构体 1.1 结构体基本概念 结构体属于用户 自定义的数据类型, 允许用户存储不同的数据类型 1.2 结构体定义和使用(cpp23.cpp) 语法:struct 结构体名{结构体成员列表}; 通过结构体创建变量的方式有三种 : struct 结构体名 变量名 struct 结构体名 变量名 = {成员1值,成员2值,...} std; //定义结构体,定义结构体时 struct 关键字 不能省略 struct Student { //以下是 结构体属性 //姓名 string name; 作用:将自定义的结构体放入到数组中方便维护 语法:struct 结构体名 数组名[元素个数] = {结构体1,结构体2,...}; 使用 结构体数组 时,struct 关键字可以省略 #define 结构体嵌套结构体(cpp25.cpp) 作用:结构体中的成员可以是另一个结构体 例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体; 1.6 结构体做函数参数(cpp33.cpp)
结构体 为什么要创建结构体类型?在我们处理复杂对象的时候,比如描述一个人的时候,它有名字,性别,身高,体重等一些方面的特征。用结构体打包描述的时候就比较方便。 结构体类型的声明 结构体类型的关键字struct。 声明的基本模板为: struct 标签 { 成员; }变量; 结构体的成员可以是不同的类型。 结构体类型的特殊声明: 匿名结构体类型,它只能使用一次。 3.对齐数:编译器默认的一个对齐数与成员大小的较小值 vs的默认对齐数位8 4.结构体的总大小为每个成员默认最大对齐数的整数倍。 3.int位段中无符号还是有符号的问题没有规定 结构体实现位段的内存分配 cstruct S { char a : 3; char b : 4; char c : 5; char d : 4
相同类型的字段可以写在一行 type Employee struct { firstName, lastName string age, salary int } ---- 3.匿名结构体声明 var employee struct { firstName, lastName string age int } ---- 4.实例化命令结构体 emp1 := Employee salary: 500, lastName: "Anderson", } emp2 := Employee{"Thomas", "Paul", 29, 800} ---- 5.匿名结构体创建 state string } type Person struct { name string age int Address } person 中的Address 其实就是匿名结构体 are equal") } else { fmt.Println("name3 and name4 are not equal") } } 如果结构体包含两个不可比较的字段
struct Student stu; 4 }; •思考一下,为什么是错误的,给个理由先? •4.结构体变量占用的内存空间是其成员所占内存之和,而且各成员在内存中按定义的顺序依次排列。 身高 }; •在16位编译器环境下,一个Student变量共占用内存:2 + 2 + 4 = 8字节。 #include <stdio.h> 2 3 // 定义一个结构体 4 struct Student { 5 int age; 6 }; 7 8 void test(struct []) { 4 // 定义一个结构体类型 5 struct Student { 6 char *name; 7 int age; 8 }
结构体和类的区别: 类里可以定义方法和属性,而结构体里只能有各种成员。 为什么有结构体: 为了表示一些复杂的数据类型,而普通的基本类型变量无法满足要求。 什么是结构体: 结构体是用户根据实际需要自己定义的复合数据类型。 : 1 struct Student st; 2 3 struct Student *pst = &st; 4 5 1.st.sid; 6 7 2.pst->sid; //pst所指向的结构体变量这的 sid成员 注意事项: 结构体变量之间只能相互赋值(可以在函数传实参的时候传递结构体变量名),不能加减乘除。 普通结构体变量和结构体指针变量作为函数传参的问题
通过结构体的成员获得结构体的地址,摘自kernel的一段宏,为了理解container_of,写了个例子 #include <stdio.h> #include <stdlib.h
1.定义区别 结构体的定义如下: struct 结构体名 { 数据类型 成员变量名1; 数据类型 成员变量名2; // 可以有更多的成员变量 }; 例如,定义一个表示学生的结构体 结构体指针可以用来指向已经存在的结构体对象,也可以用来动态创建新的结构体对象。 结构体指针可以直接通过指针访问结构体的成员变量,例如stuPtr->id表示访问指针stuPtr所指向的结构体的id成员变量。 总结起来,结构体定义了一种用户自定义的数据类型,可以包含多个成员变量;结构体指针用来指向结构体对象或动态创建的结构体对象,并可以通过指针访问结构体的成员变量。 总结起来,结构体和结构体指针的区别在于结构体表示数据类型,而结构体指针表示指向结构体的指针变量。在链表中,通过结构体表示节点,通过结构体指针操作节点的指针,从而实现链表的各种操作。
文章目录 一、结构体浅拷贝与深拷贝 二、结构体浅拷贝 三、结构体浅拷贝代码示例 一、结构体浅拷贝与深拷贝 ---- 结构体 中 嵌套了 指针 , 指针指向的内存 , 如果需要 malloc 在堆内存中 拷贝 指针变量的值 , 不会拷贝 指针变量 指向的 内存空间的 数据 ; 二、结构体浅拷贝 ---- 结构体浅拷贝 : 下面两种方式的拷贝 , 是结构体的浅拷贝 ; 直接拷贝结构体内存 : // , 拷贝到 to 指针指向的地址 ; // 结构体直接赋值 , 与上面的代码作用相同 // 该拷贝也是浅拷贝 *to = *from; 三、结构体浅拷贝代码示例 ---- 代码示例 数据类型 , 同时为该结构体类型声明 别名 * 可以直接使用 别名 结构体变量名 声明结构体类型变量 * 不需要在前面添加 struct 关键字 */ typedef struct Student 声明变量时 , 会自动分配这 5 字节内存 // 赋值时 , 可以直接使用 = 赋值字符串 char name[5]; int age; // 声明变量时 , 只会为 4
结构体与数组类似,都是由若干分量组成的,与数组不同的是,结构体的成员可以是不同类型,可以通过成员名来访问结构体的元素。 结构体的定义说明了它的组成成员,以及每个成员的数据类型。 结构变量说 明的一般形式如下: struct 结构类型名称 结构变量名; 定义结构体便是定义了一种由成员组成的复合类型,而用这种类型说明了一个变量才会产生具体的实 体。 2、结构体的高级使用 结构体数组 结构体数组是一个数组,其数组的每一个元素都是结构体类型。 在实际应用中,经常用结构体数组来 表示具有相同数据结构的一个群体,如一个班的学生档案,一个车间职工的工资表等。定义结构体数组和 结构体变量相仿,只需说明它为数组类型即可。 4、使用typedef定义类型 在 C 语言中,除系统定义的标准类型和用户自定义的结构体、共用体等类型之外,还可以使用类型说 明语句 typedef 定义新的类型来代替已有的类型。