加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang 常见疑惑总结

发布时间:2020-12-16 19:14:49 所属栏目:大数据 来源:网络整理
导读:经常会有一些朋友问go语言的一些问题和疑惑,其实好多问题在官方文档和stackoverflow里都有详细的讲解,只要你肯花时间读一遍 官方文档 和 Effective Go 基本上都有找到答案。本文总结一下大家经常问到的一些问题,长期更新。 代码都在github上, 地址 https

经常会有一些朋友问go语言的一些问题和疑惑,其实好多问题在官方文档和stackoverflow里都有详细的讲解,只要你肯花时间读一遍官方文档Effective Go基本上都有找到答案。本文总结一下大家经常问到的一些问题,长期更新。

  代码都在github上, 地址https://github.com/lpxxn/gocommonquestions

new 和make 的区别

  简单来说,new(T)用于分配内存,返回指向T类型的一个指针,指针的值为T类型的零值

    n1 := new(int) fmt.Println(n1) // console the address of n1
    fmt.Println(*n1 == 0)  zero value
 type T struct { I int A string Next *T } n2 := new(T) fmt.Println(n2) fmt.Println(n2.I == 0) fmt.Println(n2.Next == nil) fmt.Println(n2.A == "") n3 := new([]int) fmt.Println(n3) fmt.Println(*n3 == nil)

  make(T) 只能用于slice、map和channel,返回非零值的T。

m1 := make([]int,1) fmt.Println(m1) m2 := make(map[int]string) m2[0] = "abcde" m3 := make(chan int) m4 := make(chan 5)

  make 返回的是类型本身,new 返回的是指向类型的指针

相关讲解

https://stackoverflow.com/questions/9320862/why-would-i-make-or-new

https://golang.org/doc/effective_go.html#allocation_new

https://golang.org/ref/spec#The_zero_value

是否需要主动关闭channel

  除非你的程序需要等待channel关闭后做一些操作,不用主动去关闭channel。当没有地方在使用这个channel的时候go的垃圾回收系统会自动回收。

  下面的小例子就是在等待channel c1和c2关闭后,再做一些事情。  

func main() { c1 := make(chan 3) go test1(c1) for v := range c1 { fmt.Println(v) } fmt.Println(after close c1 do something") c2 := make(chan bool) go func() { time.AfterFunc(time.Second * 3,func() { close(c2) }) }() _,close := <- c2 if !close { fmt.Println(after c2 closed do something") } fmt.Println(end") } func test1(c chan<- int) { for i := 0; i < 5; i++ { c <- i } close(c) }

  相关讲解:https://stackoverflow.com/questions/8593645/is-it-ok-to-leave-a-channel-open

https://groups.google.com/forum/#!msg/golang-nuts/pZwdYRGxCIk/qpbHxRRPJdUJ

Unbuffered channel和buffered channel 区别

buffered channel

c3 := make(chan bool,128);line-height:1.5;">5)   buffered channel

buffered channel 可以持续的发送数据到channel,直到channel满为至。不用等待是否有接收channel。

如果channel满了,会等待读取channel,当有channel被读取,就会继续发送数据到channel

c3 := make(chan buffered channel go func() { 20; i++ { c3 <- i % 2 == 0 } close(c3) }() for v := range c3 { fmt.Println(v) }

unbuffered channel

下面这两种声明是一样的

c1 := make(chan 0) unbuffered channel c2 := make(chan bool) unbuffered channel

  unbuffered channel 的接收channel会一直阻塞,直到有值传给channel,也可以说发送channel会一直阻塞,至到有接收channel

unbuffered channel go func() { c1 <- false time.Sleep(time.Second * 2) c2 <- true }() fmt.Println(<-c1) fmt.Println(<-c2)

相关讲解:

https://stackoverflow.com/questions/23233381/whats-the-difference-between-c-makechan-int-and-c-makechan-int-1

https://golang.org/doc/effective_go.html

定义类型和组合类型的区别

  定义类型,也可以说是别名和组合类型的区别

  有一个Test的结构,NewTest是以Test为类型的一个定义,New2Test和New3Test都是组合类型

type Test struct { N int } func (m *Test) Name() { fmt.Println(abc")} NewTest does not inherit any functions of Test can access fields type NewTest Test New2Test is composite type,it inherit all functions of Test can access fields type New2Test struct { Test } if embedded type is pointer you must initialized it type New3Test struct { *Test }

1.定义类型NewTest 相当于一个新的类型,他不能直接调用Test的方法,但是可以访问Test的字段。如果想调用原类型的方法需要做转换

2.New2Test和New3Test都是组合类型,他俩都可以直接调用Test的方法和访问Test的字段,他俩的不同之处就是一个是值组合一个是指针组合

  3.在实例化New3Test的时候需要手动实例化*Test指针

n := NewTest{} n.N = 1 n have no method n.Name() error v := (*Test)(&n) v.Name() v2 := Test(n) v2.Name() n2 := New2Test{} n2.N = 2 n2.Name() n3 := New3Test{Test: new(Test)} access filed N will panic if you do not initialized *Test n3.N = 3 n3.Name()

  相关的解答:

https://stackoverflow.com/questions/28800672/how-to-add-new-methods-to-an-existing-type-in-go/28800807#28800807

https://golang.org/ref/spec#Type_declarations

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读