```
docs(day04): 更新README目录结构并添加内存管理图表 - 在README.md中更新目录链接,将原有的列表格式改为链接格式 - 添加Go语言结构体、指针和反射的相关文档链接 - 修改drawio图表文件,调整坐标参数和页面布局 - 增加堆栈内存管理的可视化图表,包含函数调用和变量分配示例 - 添加代码示例展示Go语言中的变量提升机制 ```
This commit is contained in:
parent
1aa8ec7f3e
commit
11aaa2d03a
@ -1,5 +1,5 @@
|
|||||||
# 结构体(2)与指针
|
# 结构体(2)与指针
|
||||||
|
|
||||||
+ [Go语言结构体](./struct/README.md)
|
+ [Go语言结构体](./struct/README.md)
|
||||||
+ Go语言指针
|
+ [Go语言指针】【](./pointer/README.md)
|
||||||
+ 扩展反射与内存对齐
|
+ [扩展: Go语言反射](./reflect/README.md)
|
||||||
16
day04/pointer/README.md
Normal file
16
day04/pointer/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# 指针
|
||||||
|
|
||||||
|
## 陷阱 2:指针指向栈变量的地址逃逸
|
||||||
|
Go 编译器会自动处理,通常无需担心:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func getPtr() *int {
|
||||||
|
v := 10
|
||||||
|
return &v // v 虽然是局部变量,但 Go 会自动提升到堆
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 作业: 实现链表节点和基本操作
|
||||||
BIN
day04/pointer/image.png
Normal file
BIN
day04/pointer/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
28
day04/pointer/link_list.drawio
Normal file
28
day04/pointer/link_list.drawio
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<mxfile host="65bd71144e">
|
||||||
|
<diagram id="mRYyQN2MmenF_MetcyJE" name="第 1 页">
|
||||||
|
<mxGraphModel dx="1134" dy="530" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="4" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="2" value="Node" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="120" y="200" width="170" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="6" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="3" value="Node" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="370" y="200" width="170" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="5" value="Node" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="610" y="200" width="170" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="7" value="LinkList : 访问效果低,&nbsp; 修改成本低<div><br></div><div>slice: 访问效果高, 不支持修改</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="90" y="80" width="270" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
110
day04/reflect/README.md
Normal file
110
day04/reflect/README.md
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# 反射与内存对齐(扩展)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 反射获取值与类型
|
||||||
|
|
||||||
|
```go
|
||||||
|
// obj -> []byte 类型是 any
|
||||||
|
func JsonEncode(obj any) []byte {
|
||||||
|
// 反射获取类型信息
|
||||||
|
ot := reflect.TypeOf(obj)
|
||||||
|
fmt.Println("类型名称:", ot.Name())
|
||||||
|
fmt.Println("类型种类:", ot.Kind())
|
||||||
|
// 类型名称: TranficTool
|
||||||
|
// 类型种类: struct
|
||||||
|
|
||||||
|
// 反射获取值信息
|
||||||
|
ov := reflect.ValueOf(obj)
|
||||||
|
fmt.Println("值:", ov)
|
||||||
|
// 值: {自行车 20 黑色}
|
||||||
|
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 反射获取stuct的字段和 Struct Tag
|
||||||
|
|
||||||
|
```go
|
||||||
|
// obj -> []byte 类型是 any
|
||||||
|
func JsonEncode(obj any) []byte {
|
||||||
|
// 反射获取类型信息
|
||||||
|
ot := reflect.TypeOf(obj)
|
||||||
|
fmt.Println("类型名称:", ot.Name())
|
||||||
|
fmt.Println("类型种类:", ot.Kind())
|
||||||
|
// 类型名称: TranficTool
|
||||||
|
// 类型种类: struct
|
||||||
|
|
||||||
|
// 反射获取值信息
|
||||||
|
ov := reflect.ValueOf(obj)
|
||||||
|
fmt.Println("值:", ov)
|
||||||
|
// 反射获取结构体字段信息(TranficTool)
|
||||||
|
for i := 0; i < ot.NumField(); i++ {
|
||||||
|
field := ot.Field(i)
|
||||||
|
fieldValue := ov.Field(i)
|
||||||
|
fmt.Printf(" 字段 %d: 名称=%s, 类型=%s, Tag=%s, JsonTag=%s, Value=%v\n",
|
||||||
|
i, field.Name, field.Type.Name(), field.Tag, field.Tag.Get("json"), fieldValue.Interface())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 类型名称: TranficTool
|
||||||
|
// 类型种类: struct
|
||||||
|
// 值: {自行车 20 黑色}
|
||||||
|
// 字段 0: 名称=Name, 类型=string, Tag=json:"name", JsonTag=name, Value=自行车
|
||||||
|
// 字段 1: 名称=Speed, 类型=int, Tag=json:"speed", JsonTag=speed, Value=20
|
||||||
|
// 字段 2: 名称=Color, 类型=string, Tag=json:"color", JsonTag=color, Value=黑色
|
||||||
|
//
|
||||||
|
// 很容易就可以构建出 Json 数据
|
||||||
|
// {"name":"自行车","speed":20,"color":"黑色"}
|
||||||
|
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 动态修改对象
|
||||||
|
|
||||||
|
```go
|
||||||
|
// obj -> []byte 类型是 any
|
||||||
|
func JsonEncode(obj any) []byte {
|
||||||
|
// 反射获取类型信息
|
||||||
|
ot := reflect.TypeOf(obj)
|
||||||
|
|
||||||
|
if ot.Kind() != reflect.Pointer && ot.Kind() != reflect.Struct {
|
||||||
|
panic("必须是结构体指针类型")
|
||||||
|
}
|
||||||
|
|
||||||
|
ot = ot.Elem() // 获取指针指向的类型
|
||||||
|
|
||||||
|
fmt.Println("类型名称:", ot.Name())
|
||||||
|
fmt.Println("类型种类:", ot.Kind())
|
||||||
|
// 类型名称: TranficTool
|
||||||
|
// 类型种类: struct
|
||||||
|
|
||||||
|
// 反射获取值信息
|
||||||
|
ov := reflect.ValueOf(obj).Elem()
|
||||||
|
fmt.Println("值:", ov)
|
||||||
|
// 反射获取结构体字段信息(TranficTool)
|
||||||
|
for i := 0; i < ot.NumField(); i++ {
|
||||||
|
field := ot.Field(i)
|
||||||
|
fieldValue := ov.Field(i)
|
||||||
|
if field.Name == "Name" {
|
||||||
|
fmt.Println("发现 Name 字段,准备进行特殊处理...")
|
||||||
|
fieldValue.SetString(fieldValue.String() + "_changed")
|
||||||
|
}
|
||||||
|
fmt.Printf(" 字段 %d: 名称=%s, 类型=%s, Tag=%s, JsonTag=%s, Value=%v\n",
|
||||||
|
i, field.Name, field.Type.Name(), field.Tag, field.Tag.Get("json"), fieldValue.Interface())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 类型名称: TranficTool
|
||||||
|
// 类型种类: struct
|
||||||
|
// 值: {自行车 20 黑色}
|
||||||
|
// 字段 0: 名称=Name, 类型=string, Tag=json:"name", JsonTag=name, Value=自行车
|
||||||
|
// 字段 1: 名称=Speed, 类型=int, Tag=json:"speed", JsonTag=speed, Value=20
|
||||||
|
// 字段 2: 名称=Color, 类型=string, Tag=json:"color", JsonTag=color, Value=黑色
|
||||||
|
//
|
||||||
|
// 很容易就可以构建出 Json 数据
|
||||||
|
// {"name":"自行车","speed":20,"color":"黑色"}
|
||||||
|
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
```
|
||||||
64
day04/reflect/main.go
Normal file
64
day04/reflect/main.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// bike 对象
|
||||||
|
bike := TranficTool{Name: "自行车", Speed: 20, Color: "黑色"}
|
||||||
|
JsonEncode(&bike)
|
||||||
|
fmt.Println(bike)
|
||||||
|
}
|
||||||
|
|
||||||
|
// obj -> []byte 类型是 any
|
||||||
|
func JsonEncode(obj any) []byte {
|
||||||
|
// 反射获取类型信息
|
||||||
|
ot := reflect.TypeOf(obj)
|
||||||
|
|
||||||
|
if ot.Kind() != reflect.Pointer && ot.Kind() != reflect.Struct {
|
||||||
|
panic("必须是结构体指针类型")
|
||||||
|
}
|
||||||
|
|
||||||
|
ot = ot.Elem() // 获取指针指向的类型
|
||||||
|
|
||||||
|
fmt.Println("类型名称:", ot.Name())
|
||||||
|
fmt.Println("类型种类:", ot.Kind())
|
||||||
|
// 类型名称: TranficTool
|
||||||
|
// 类型种类: struct
|
||||||
|
|
||||||
|
// 反射获取值信息
|
||||||
|
ov := reflect.ValueOf(obj).Elem()
|
||||||
|
fmt.Println("值:", ov)
|
||||||
|
// 反射获取结构体字段信息(TranficTool)
|
||||||
|
for i := 0; i < ot.NumField(); i++ {
|
||||||
|
field := ot.Field(i)
|
||||||
|
fieldValue := ov.Field(i)
|
||||||
|
if field.Name == "Name" {
|
||||||
|
fmt.Println("发现 Name 字段,准备进行特殊处理...")
|
||||||
|
fieldValue.SetString(fieldValue.String() + "_changed")
|
||||||
|
}
|
||||||
|
fmt.Printf(" 字段 %d: 名称=%s, 类型=%s, Tag=%s, JsonTag=%s, Value=%v\n",
|
||||||
|
i, field.Name, field.Type.Name(), field.Tag, field.Tag.Get("json"), fieldValue.Interface())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 类型名称: TranficTool
|
||||||
|
// 类型种类: struct
|
||||||
|
// 值: {自行车 20 黑色}
|
||||||
|
// 字段 0: 名称=Name, 类型=string, Tag=json:"name", JsonTag=name, Value=自行车
|
||||||
|
// 字段 1: 名称=Speed, 类型=int, Tag=json:"speed", JsonTag=speed, Value=20
|
||||||
|
// 字段 2: 名称=Color, 类型=string, Tag=json:"color", JsonTag=color, Value=黑色
|
||||||
|
//
|
||||||
|
// 很容易就可以构建出 Json 数据
|
||||||
|
// {"name":"自行车","speed":20,"color":"黑色"}
|
||||||
|
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TranficTool struct {
|
||||||
|
// `` 表示字符串 都是 Struct Tag, 结构体标签,lib 反射使用
|
||||||
|
Name string `json:"name"`
|
||||||
|
Speed int `json:"speed"`
|
||||||
|
Color string `json:"color"`
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="5nK-vBOAah09B86iugSh" name="第 1 页">
|
<diagram id="5nK-vBOAah09B86iugSh" name="第 1 页">
|
||||||
<mxGraphModel dx="1134" dy="607" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="1134" dy="435" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
@ -70,6 +70,53 @@
|
|||||||
<mxPoint x="560" y="120" as="targetPoint"/>
|
<mxPoint x="560" y="120" as="targetPoint"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
|
<mxCell id="22" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="100" y="720" width="120" height="250" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="23" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="350" y="720" width="120" height="250" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="24" value="堆: Heap<div><br></div><div>灵活(复杂)</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="384" y="660" width="60" height="50" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="25" value="栈 : Stack<div><br></div><div>高效(基础值)</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="120" y="660" width="80" height="50" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="26" value="fn a" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="100" y="920" width="120" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="27" value="fn b" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="100" y="890" width="120" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="34" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="28" target="30">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="35" value="变量提升" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="34">
|
||||||
|
<mxGeometry x="0.1077" y="-3" relative="1" as="geometry">
|
||||||
|
<mxPoint as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="28" value="fn c (数据 v)" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="100" y="860" width="120" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="29" value="<pre style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Menlo, Monaco, Consolas, &quot;Liberation Mono&quot;, &quot;Courier New&quot;, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 16px; overflow-wrap: normal; padding: 16px; line-height: 1.45; background-color: rgb(246, 248, 250); border-radius: 3px; min-height: 52px; tab-size: 4; color: rgb(64, 72, 91); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><code class="hljs hljs-go" style="box-sizing: border-box; font-family: SFMono-Regular, Menlo, Monaco, Consolas, &quot;Liberation Mono&quot;, &quot;Courier New&quot;, monospace; display: inline; overflow: visible; padding: 0px; color: rgba(0, 0, 0, 0.8); background: transparent; text-size-adjust: none; font-size: 14px; margin: 0px; border-radius: 6px; border: 0px; white-space: pre; font-weight: normal; word-break: normal; line-height: inherit; overflow-wrap: normal;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; color: rgb(51, 51, 51); font-weight: bold;">func</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(153, 0, 0); font-weight: bold;">getPtr</span><span class="hljs-params" style="box-sizing: border-box;">()</span> *<span class="hljs-title" style="box-sizing: border-box; color: rgb(153, 0, 0); font-weight: bold;">int</span></span> {
 v := <span class="hljs-number" style="box-sizing: border-box; color: rgb(0, 128, 128);">10</span>
 <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(51, 51, 51); font-weight: bold;">return</span> &amp;v <span class="hljs-comment" style="box-sizing: border-box; color: rgb(153, 153, 136); font-style: italic;">// v 虽然是局部变量,但 Go 会自动提升到堆</span>
}</code></pre>" style="text;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="40" y="990" width="490" height="150" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="30" value="v" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="350" y="860" width="120" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="36" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="31" target="30">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="31" value="ptr" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="100" y="800" width="120" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="33" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="32" target="31">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="32" value="struct" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="350" y="780" width="120" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user