博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang 常见疑惑总结
阅读量:4562 次
发布时间:2019-06-08

本文共 3626 字,大约阅读时间需要 12 分钟。

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

  代码都在github上, 地址 

 

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 int, 5)

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

 

相关讲解

 

是否需要主动关闭channel

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

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

func main() {    c1 := make(chan int, 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)}

简单测试垃圾回收channel

func createChan() chan int64{    c := make(chan int64, 10000)    c <- 1    return c}func main() {    RM()    for i := 0; i < 10; i++ {        c := createChan()        c <- 2        RM()        runtime.GC()    }    RM()}func RM(){    var m runtime.MemStats    runtime.ReadMemStats(&m)    fmt.Println(m.Alloc)}

  

相关讲解:

Unbuffered channel和buffered channel 区别

buffered channel

c3 := make(chan bool, 5)  // buffered channel

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

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

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

 

 unbuffered channel

下面这两种声明是一样的

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

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

c1 := make(chan bool, 0)  // unbuffered channel    c2 := make(chan bool)     // unbuffered channel    go func() {        c1 <- false        time.Sleep(time.Second * 2)        c2 <- true    }()    fmt.Println(<-c1)    fmt.Println(<-c2)

相关讲解:

 

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

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

    有一个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 fieldstype NewTest Test// New2Test is composite type, it inherit all functions of Test// can access fieldstype New2Test struct {    Test}// if embedded type is pointer you must initialized ittype 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://www.cnblogs.com/li-peng/p/8990701.html

你可能感兴趣的文章
判断连通图是否有环(并查集)
查看>>
汽车之家面试题2016
查看>>
POJ-数据结构-优先队列模板
查看>>
【HAOI2006】旅行(并查集暴力)
查看>>
css实现文本超出部分省略号显示
查看>>
留言板
查看>>
vue-router组件状态刷新消失的问题
查看>>
Android UI开发第十四篇——可以移动的悬浮框
查看>>
java8的一些用法
查看>>
(十)Hive分析窗口函数(二) NTILE,ROW_NUMBER,RANK,DENSE_RANK
查看>>
2018-11-19站立会议内容
查看>>
STM32 通用定时器相关寄存器
查看>>
【题解】1621. 未命名
查看>>
字符串加密算法
查看>>
Oracle的实例恢复解析
查看>>
UICollectionView cellForItemAt 不被调用
查看>>
巧用网盘托管私人Git项目
查看>>
python全栈脱产第19天------常用模块---shelve模块、xml模块、configparser模块、hashlib模块...
查看>>
[LeetCode] House Robber
查看>>
virtualbox中kali虚拟机安装增强功能
查看>>