Skip to content

Commit ea50b40

Browse files
committed
init
1 parent 41f6f85 commit ea50b40

File tree

3 files changed

+340
-0
lines changed

3 files changed

+340
-0
lines changed

11.反射Reflection.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
## 反射Reflection
2+
-反射可以大大提高程序的灵活性,使得 `interface{}` 有更大的发挥余地
3+
-反射使用 `TypeOf``ValueOf` 函数从接口中获取目标对象信息
4+
-反射会将匿名字段作为独立字段(匿名字段本质)
5+
-想要利用反射修改对象状态,前提是 `interface.data``settable` ,即 `pointer-interface`
6+
-通过反射可以 “动态” 调用方法
7+
8+
import (
9+
"fmt"
10+
"reflect"
11+
)
12+
13+
type User struct {
14+
Id int
15+
Name string
16+
Age int
17+
}
18+
19+
func (u User) Hello() {
20+
fmt.Println("Hello World.")
21+
}
22+
23+
func main() {
24+
u := User{1, "ok", 12}
25+
Info(u)
26+
}
27+
28+
func Info(o interface{}) {
29+
//结构名称
30+
t := reflect.TypeOf(o)
31+
fmt.Println("Type:", t.Name())
32+
33+
//判断传入参数类型,比如 main() 中使用 Info(&u) 时
34+
if k := t.Kind(); k != reflect.Struct {
35+
fmt.Println("error")
36+
return
37+
}
38+
39+
//字段信息
40+
v := reflect.ValueOf(o)
41+
fmt.Println("Fields:")
42+
for i := 0; i < t.NumField(); i++ {
43+
f := t.Field(i)
44+
val := v.Field(i).Interface()
45+
fmt.Printf("%6s: %v = %v\n", f.Name, f.Type, val)
46+
}
47+
48+
//方法信息
49+
for i := 0; i < t.NumMethod(); i++ {
50+
m := t.Method(i)
51+
fmt.Printf("%6s: %v\n", m.Name, m.Type)
52+
}
53+
}
54+
55+
嵌套反射获取信息
56+
57+
import (
58+
"fmt"
59+
"reflect"
60+
)
61+
62+
type User struct {
63+
Id int
64+
Name string
65+
Age int
66+
}
67+
68+
type Manager struct {
69+
User
70+
title string
71+
}
72+
73+
func main() {
74+
m := Manager{User: User{1, "Ok", 2}, title: "999"}
75+
t := reflect.TypeOf(m)
76+
77+
fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 1}))
78+
}
79+
80+
修改变量
81+
82+
import (
83+
"fmt"
84+
"reflect"
85+
)
86+
87+
func main() {
88+
x := 123
89+
v := reflect.ValueOf(&x)
90+
v.Elem().SetInt(999)
91+
92+
fmt.Println(x)
93+
}
94+
95+
修改结构值
96+
97+
import (
98+
"fmt"
99+
"reflect"
100+
)
101+
102+
type User struct {
103+
Id int
104+
Name string
105+
Age int
106+
}
107+
108+
func main() {
109+
u := User{1, "OK", 2}
110+
Set(&u)
111+
fmt.Println(u)
112+
}
113+
114+
func Set(o interface{}) {
115+
v := reflect.ValueOf(o)
116+
117+
if v.Kind() == reflect.Ptr && !v.Elem().CanSet() {
118+
fmt.Println("error")
119+
return
120+
} else {
121+
v = v.Elem()
122+
}
123+
124+
//判断字段是否存在
125+
f := v.FieldByName("Name")
126+
if !f.IsValid() {
127+
fmt.Println("BAD")
128+
return
129+
}
130+
131+
if f.Kind() == reflect.String {
132+
f.SetString("BYEBYE")
133+
}
134+
}
135+
136+
通过反射“动态”调用
137+
138+
import (
139+
"fmt"
140+
"reflect"
141+
)
142+
143+
type User struct {
144+
Id int
145+
Name string
146+
Age int
147+
}
148+
149+
func (u User) Hello(name string) {
150+
fmt.Println("Hello", name, ", my name is", u.Name)
151+
}
152+
153+
func main() {
154+
u := User{1, "OK", 2}
155+
v := reflect.ValueOf(u)
156+
//获取方法
157+
mv := v.MethodByName("Hello")
158+
159+
args := []reflect.Value{reflect.ValueOf("joe")}
160+
//动态调用
161+
mv.Call(args)
162+
}

11.接口Interface.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## 接口Interface
2+
-接口是一个或多个方法签名的集合
3+
-只要某个类型拥有该接口的索引方法签名,即算实现该接口,无需显示声明实现了哪个接口,这称为 `Structural Typing`
4+
-接口只有方法声明,没有实现,没有数据字段
5+
-接口可以匿名嵌入其他接口,,即嵌入到结构中
6+
-将对象赋值给接口,会发生拷贝,而接口内部存储的是指向这个复制品的指针,即无法修改复制品的状态,也无法获取指针
7+
-只有当接口存储的类型和对象都为 `nil` 时,接口才等于 `nil`
8+
-接口调用不会做 `receiver` 的字段转换
9+
-接口同样支持匿名字段方法
10+
接口也可实现类似 `OOP` 中的多态
11+
-空接口可以作为任何类型数据的容器
12+
13+
type USB interface {
14+
Name() string
15+
Connect()
16+
}
17+
18+
type PhoneConnecter struct {
19+
name string
20+
}
21+
22+
func (pc PhoneConnecter) Name() string {
23+
return pc.name
24+
}
25+
26+
func (pc PhoneConnecter) Connect() {
27+
fmt.Println("Connect:", pc.name)
28+
}
29+
30+
func main() {
31+
var a USB
32+
a = PhoneConnecter{"THINKPAD"}
33+
a.Connect()
34+
}
35+
36+
## 类型断言
37+
-通过类型断言的 `pk pattern` 可以批判的接口中的数据类型
38+
-使用 `type switch` 则可针对空接口进行比较全面的类型判断
39+
40+
## 接口转换
41+
-可以将拥有超集的接口转换为子集的接口

12.并发Concurrency.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
## 并发 `concurrency`
2+
-从源码解析来看, `goroutine` 只是由官方实现的超级 “线程池” 而已
3+
-并发部署并行
4+
-并发主要由切换时间片段来实现 “同时” 运行,并行则是直接利用多核实现多线程的运行,但 Go 可以设置使用核数,以发挥多核计算机的能力
5+
6+
import (
7+
"fmt"
8+
"time"
9+
)
10+
11+
func main() {
12+
go Go()
13+
//等待两秒
14+
time.Sleep(2 * time.Second)
15+
}
16+
17+
func Go() {
18+
fmt.Println("Go Go Go!!!")
19+
}
20+
21+
**`goroutine` 奉行通过通信来共享内存,而不是共享内存来通信**
22+
## `channel`
23+
-`channel``goroutine` 沟通的桥梁,大都是阻塞同步的
24+
-通过 `make` 创建, `close` 关闭
25+
-`channel` 时引用类型
26+
-可以使用 `for range` 来迭代不断操作 `channel`
27+
-可以设置单向或双向通道
28+
-可以设置缓存大小,在未被填满前不会发生阻塞
29+
30+
func main() {
31+
c := make(chan bool)
32+
go func() {
33+
fmt.Println("Go Go Go!!!")
34+
c <- true
35+
close(c)
36+
}()
37+
for v := range c {
38+
fmt.Println(v)
39+
}
40+
}
41+
42+
## `select`
43+
-可处理一个或多个 `channel` 的发送和接收
44+
-同时有多个可用的 `channel`是按随机顺序处理
45+
-可用空的 `select` 来阻塞 `main` 函数
46+
-可设置超时
47+
48+
func main() {
49+
c1, c2 := make(chan int), make(chan string)
50+
o := make(chan bool)
51+
go func() {
52+
for {
53+
select {
54+
case v, ok := <-c1:
55+
if !ok {
56+
o <- true
57+
break
58+
}
59+
fmt.Println("c1:",v)
60+
61+
case v, ok := <-c2:
62+
if !ok {
63+
o <- true
64+
break
65+
}
66+
fmt.Println("c2:",v)
67+
}
68+
}
69+
}()
70+
c1 <- 1
71+
c2 <- "hi"
72+
c1 <- 3
73+
c2 <- "hello"
74+
75+
close(c1)
76+
77+
<-o
78+
}
79+
80+
`select` 发送
81+
82+
func main() {
83+
c := make(chan int)
84+
go func() {
85+
for v := range c {
86+
fmt.Println(v)
87+
}
88+
}()
89+
90+
for {
91+
select {
92+
case c <- 0:
93+
case c <- 1:
94+
}
95+
}
96+
97+
}
98+
99+
`select` 设置超时
100+
101+
import (
102+
"fmt"
103+
"time"
104+
)
105+
106+
func main() {
107+
c := make(chan bool)
108+
109+
select {
110+
case v:= <-c:
111+
fmt.Println(v)
112+
case <-time.After(3 * time.Second):
113+
fmt.Println("Timeout")
114+
}
115+
}
116+
117+
课后习题
118+
119+
var c chan string
120+
121+
func Pingpang() {
122+
i := 0
123+
for {
124+
fmt.Println(<-c)
125+
c <- fmt.Sprintf("From Pingpang: Hi, #%d", i)
126+
i++
127+
}
128+
}
129+
130+
func main() {
131+
c = make(chan string)
132+
go Pingpang()
133+
for i := 0; i < 10; i++ {
134+
c <- fmt.Sprintf("From Pingpang: Hello, #%d", i)
135+
fmt.Println(<-c)
136+
}
137+
}

0 commit comments

Comments
 (0)