go知识整理20191228(1-50)

andy_wb_22 · · 224 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

## 第一天 ``` package main import ( "fmt" ) func main() { defer_call() } func defer_call() { defer func() { fmt.Println("打印前") }() defer func() { fmt.Println("打印中") }() defer func() { fmt.Println("打印后") }() panic("触发异常") } 答案: 打印后 打印中 打印前 panic: 触发异常 解析:defer 的执行顺序是后进先出。当出现 panic 语句的时候,会先按照 defer 的后进先出的顺序执行,最后才会执行panic。 ``` ## 第二天 ``` func main() { slice := []int{0,1,2,3} m := make(map[int]*int) for key,val := range slice { m[key] = &val } for k,v := range m { fmt.Println(k,"->",*v) } } ``` ``` 0 -> 3 1 -> 3 2 -> 3 3 -> 3 ``` ## 第3天 ``` ``` ## 第6天 ``` 1.通过指针变量 p 访问其成员变量 name,有哪几种方式? A.p.name B.(&p).name C.(*p).name D.p->name 参考答案:AC 参考解析:& 取址运算符,* 指针解引用。 2.下面这段代码能否通过编译?如果通过,输出什么? package main import "fmt" type MyInt1 int type MyInt2 = int func main() { var i int =0 var i1 MyInt1 = i var i2 MyInt2 = i fmt.Println(i1,i2) } 参考答案:编译不通过,cannot use i (type int) as type MyInt1 in assignment 参考解析:这道题考的是类型别名与类型定义的区别。 第 5 行代码是基于类型 int 创建了新类型 MyInt1,第 6 行代码是创建了 int 的类型别名 MyInt2,注意类型别名的定义时 = 。所以,第 10 行代码相当于是将 int 类型的变量赋值给 MyInt1 类型的变量,Go 是强类型语言,编译当然不通过;而 MyInt2 只是 int 的别名,本质上还是 int,可以赋值。 第 10 行代码的赋值可以使用强制类型转化 var i1 MyInt1 = MyInt1(i). ``` ## ``` func main() { s := make([]int, 5) s = append(s, 1, 2, 3) fmt.Println(s) } ``` ## 8map线程安全 ``` type UserAges struct { ages map[string]int sync.Mutex } func (ua *UserAges) Add(name string, age int) { ua.Lock() defer ua.Unlock() ua.ages[name] = age } func (ua *UserAges) Get(name string) int { if age, ok := ua.ages[name]; ok { return age } return -1 } 考点:map线程安全 解答:可能会出现fatal error: concurrent map read and map write. 修改一下看看效果 func (ua *UserAges) Get(name string) int { ua.Lock() defer ua.Unlock() if age, ok := ua.ages[name]; ok { return age } return -1 } ``` ## 9chan缓存池 ``` func (set *threadSafeSet) Iter() <-chan interface{} { ch := make(chan interface{}) go func() { set.RLock() for elem := range set.s { ch <- elem } close(ch) set.RUnlock() }() return ch } 考点:chan缓存池 解答:看到这道题,我也在猜想出题者的意图在哪里。 chan?sync.RWMutex?go?chan缓存池?迭代? 所以只能再读一次题目,就从迭代入手看看。 既然是迭代就会要求set.s全部可以遍历一次。但是chan是为缓存的,那就代表这写入一次就会阻塞。 我们把代码恢复为可以运行的方式,看看效果. package main import ( "sync" "fmt" ) //下面的迭代会有什么问题? type threadSafeSet struct { sync.RWMutex s []interface{} } func (set *threadSafeSet) Iter() <-chan interface{} { // ch := make(chan interface{}) // 解除注释看看! ch := make(chan interface{},len(set.s)) go func() { set.RLock() for elem,value := range set.s { ch <- elem println("Iter:",elem,value) } close(ch) set.RUnlock() }() return ch } func main() { th:=threadSafeSet{ s:[]interface{}{"1","2"}, } v:=<-th.Iter() fmt.Sprintf("%s%v","ch",v) } ``` ## 10 以下代码能编译过去吗?为什么?golang的方法集 ``` package main import ( "fmt" ) type People interface { Speak(string) string } type Stduent struct{} func (stu *Stduent) Speak(think string) (talk string) { if think == "bitch" { talk = "You are a good boy" } else { talk = "hi" } return } func main() { var peo People = Stduent{} think := "bitch" fmt.Println(peo.Speak(think)) } 考点:golang的方法集 解答:编译不通过! 做错了!?说明你对golang的方法集还有一些疑问。 一句话:golang的方法集仅仅影响接口实现和方法表达式转化,与通过实例或者指针调用方法无关。 ``` ## 11. 以下代码打印出来什么内容,说出为什么。 ``` ```

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459

224 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传