Skip to content

Commit e5b9936

Browse files
author
aceld
committed
up first
1 parent 8cbc1e2 commit e5b9936

File tree

187 files changed

+7169
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

187 files changed

+7169
-2
lines changed

1、数据定义.md

+296
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
[TOC]
2+
3+
## 1、数据定义
4+
5+
6+
7+
### (1).函数返回值问题
8+
9+
> 下面代码是否可以编译通过?
10+
11+
> test1.go
12+
13+
```go
14+
package main
15+
16+
/*
17+
下面代码是否编译通过?
18+
*/
19+
func myFunc(x,y int)(sum int,error){
20+
return x+y,nil
21+
}
22+
23+
func main() {
24+
num, err := myFunc(1, 2)
25+
fmt.Println("num = ", num)
26+
}
27+
28+
```
29+
30+
31+
32+
答案:
33+
34+
编译报错理由:
35+
36+
```bash
37+
# command-line-arguments
38+
./test1.go:6:21: syntax error: mixed named and unnamed function parameters
39+
```
40+
41+
42+
43+
> 考点:函数返回值命名
44+
45+
> 结果:编译出错。
46+
47+
> 在函数有多个返回值时,只要有一个返回值有指定命名,其他的也必须有命名。 如果返回值有有多个返回值必须加上括号; 如果只有一个返回值并且有命名也需要加上括号; 此处函数第一个返回值有sum名称,第二个未命名,所以错误。
48+
49+
50+
51+
52+
53+
### (2).结构体比较问题
54+
55+
> 下面代码是否可以编译通过?为什么?
56+
57+
> test2.go
58+
59+
```go
60+
package main
61+
62+
import "fmt"
63+
64+
func main() {
65+
66+
sn1 := struct {
67+
age int
68+
name string
69+
}{age: 11, name: "qq"}
70+
71+
sn2 := struct {
72+
age int
73+
name string
74+
}{age: 11, name: "qq"}
75+
76+
if sn1 == sn2 {
77+
fmt.Println("sn1 == sn2")
78+
}
79+
80+
sm1 := struct {
81+
age int
82+
m map[string]string
83+
}{age: 11, m: map[string]string{"a": "1"}}
84+
85+
sm2 := struct {
86+
age int
87+
m map[string]string
88+
}{age: 11, m: map[string]string{"a": "1"}}
89+
90+
if sm1 == sm2 {
91+
fmt.Println("sm1 == sm2")
92+
}
93+
}
94+
95+
```
96+
97+
结果
98+
99+
编译不通过
100+
101+
```bash
102+
./test2.go:31:9: invalid operation: sm1 == sm2 (struct containing map[string]string cannot be compared)
103+
104+
```
105+
106+
考点:**结构体比较**
107+
108+
> **结构体比较规则注意1**:只有相同类型的结构体才可以比较,结构体是否相同不但与属性类型个数有关,还与属性顺序相关.
109+
110+
比如:
111+
112+
```go
113+
sn1 := struct {
114+
age int
115+
name string
116+
}{age: 11, name: "qq"}
117+
118+
sn3:= struct {
119+
name string
120+
age int
121+
}{age:11, name:"qq"}
122+
```
123+
124+
`sn3``sn1`就不是相同的结构体了,不能比较。
125+
126+
127+
128+
> **结构体比较规则注意2**:结构体是相同的,但是结构体属性中有不可以比较的类型,如`map`,`slice`,则结构体不能用`==`比较。
129+
130+
131+
132+
可以使用reflect.DeepEqual进行比较
133+
134+
```go
135+
if reflect.DeepEqual(sm1, sm2) {
136+
fmt.Println("sm1 == sm2")
137+
} else {
138+
fmt.Println("sm1 != sm2")
139+
}
140+
```
141+
142+
143+
144+
145+
146+
### (3).string与nil类型
147+
148+
> 下面代码是否能够编译通过?为什么?
149+
150+
> test3.go
151+
152+
```go
153+
package main
154+
155+
import (
156+
"fmt"
157+
)
158+
159+
func GetValue(m map[int]string, id int) (string, bool) {
160+
if _, exist := m[id]; exist {
161+
return "存在数据", true
162+
}
163+
return nil, false
164+
}
165+
166+
func main() {
167+
intmap:=map[int]string{
168+
1:"a",
169+
2:"bb",
170+
3:"ccc",
171+
}
172+
173+
v,err:=GetValue(intmap,3)
174+
fmt.Println(v,err)
175+
}
176+
177+
```
178+
179+
考点:**函数返回值类型**
180+
181+
答案:编译不会通过。
182+
183+
分析:
184+
185+
nil 可以用作 interface、function、pointer、map、slice 和 channel 的“空值”。但是如果不特别指定的话,Go 语言不能识别类型,所以会报错。通常编译的时候不会报错,但是运行是时候会报:`cannot use nil as type string in return argument`.
186+
187+
所以将`GetValue`函数改成如下形式就可以了
188+
189+
```go
190+
func GetValue(m map[int]string, id int) (string, bool) {
191+
if _, exist := m[id]; exist {
192+
return "存在数据", true
193+
}
194+
return "不存在数据", false
195+
}
196+
```
197+
198+
### (4) 常量
199+
200+
> 下面函数有什么问题?
201+
202+
> test4.go
203+
204+
```go
205+
package main
206+
207+
const cl = 100
208+
209+
var bl = 123
210+
211+
func main() {
212+
println(&bl,bl)
213+
println(&cl,cl)
214+
}
215+
```
216+
217+
解析
218+
219+
考点:**常量**
220+
常量不同于变量的在运行期分配内存,常量通常会被编译器在预处理阶段直接展开,作为指令数据使用,
221+
222+
```
223+
cannot take the address of cl
224+
```
225+
226+
227+
228+
内存四区概念:
229+
230+
#### A.数据类型本质:
231+
232+
​ 固定内存大小的别名
233+
234+
#### B. 数据类型的作用:
235+
236+
​ 编译器预算对象(变量)分配的内存空间大小。
237+
238+
![](images/108-数据变量.png)
239+
240+
241+
242+
243+
244+
#### C. 内存四区
245+
246+
![](images/107-内存4区.jpeg)
247+
248+
流程说明
249+
250+
1、操作系统把物理硬盘代码load到内存
251+
252+
2、操作系统把c代码分成四个区
253+
254+
3、操作系统找到main函数入口执行
255+
256+
257+
258+
##### 栈区(Stack):
259+
260+
​ 空间较小,要求数据读写性能高,数据存放时间较短暂。由编译器自动分配和释放,存放函数的参数值、函数的调用流程方法地址、局部变量等(局部变量如果产生逃逸现象,可能会挂在在堆区)
261+
262+
263+
264+
##### 堆区(heap):
265+
266+
​ 空间充裕,数据存放时间较久。一般由开发者分配及释放(但是Golang中会根据变量的逃逸现象来选择是否分配到栈上或堆上),启动Golang的GC由GC清除机制自动回收。
267+
268+
269+
270+
##### 全局区-静态全局变量区:
271+
272+
​ 全局变量的开辟是在程序在`main`之前就已经放在内存中。而且对外完全可见。即作用域在全部代码中,任何同包代码均可随时使用,在变量会搞混淆,而且在局部函数中如果同名称变量使用`:=`赋值会出现编译错误。
273+
274+
​ 全局变量最终在进程退出时,由操作系统回收。
275+
276+
> 我么在开发的时候,尽量减少使用全局变量的设计
277+
278+
279+
280+
###### 全局区-常量区:
281+
282+
​ 常量区也归属于全局区,常量为存放数值字面值单位,即不可修改。或者说的有的常量是直接挂钩字面值的。
283+
284+
比如:
285+
286+
```go
287+
const cl = 10
288+
```
289+
290+
cl是字面量10的对等符号。
291+
292+
所以在golang中,常量是无法取出地址的,因为字面量符号并没有地址而言。
293+
294+
---
295+
296+

0 commit comments

Comments
 (0)