Golang知识点汇总
作者:互联网
for select时,如果通道已经关闭会怎么样?如果只有一个case呢?
select用于监听channel,在通道关闭时,channel会返回类型的空值,直接用`<-`取值时无论通道是否关闭都会有值返回.所以当使用select监听通道时,如果某个channel已经关闭,则每次都会执行这个case;
如果只有一个case,当通道关闭后会进入死循环.
var c = make(chan int) go func() { time.Sleep(3 * time.Second) c <- 8 close(c) }() for { time.Sleep(1 * time.Second) select { case s, ok := <-c: fmt.Println(s, ok) default: fmt.Println("i am default") } } ~~~~~~~~~~~~~~~结果:~~~~~~~~~~~~~~~~~~~~ i am default i am default 8 true 0 false 0 false 0 false 0 false exit status 0xc000013a ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
处理办法: 可以通过对`ok`的值进行判断的方式处理:
var c = make(chan int) go func() { time.Sleep(3 * time.Second) c <- 8 close(c) }() for { time.Sleep(1 * time.Second) select { case s, ok := <-c: fmt.Println(s, ok) if !ok { c = nil } default: fmt.Println("i am default") } } ~~~~~~~~~~~~~~~~结果:~~~~~~~~~~~~~~~~~~~~~ i am default i am default 8 true 0 false i am default i am default i am default i am default exit status 0xc000013a ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nil切片和空切片的区别
切片是数组的引用,nil切片是一个未初始化的切片,它指向的数组地址为0, 相当于尚未被分配地址;空切片是已经初始化完成的切片,只不过这个切片内不含任何的值,它引用的数组是有地址的,并且这个地址固定.
var ( a []int b = make([]int, 0) c = make([]int, 0) ) // SliceHeader是切片的底层结构 fmt.Printf("a: %+v\n", *(*reflect.SliceHeader)(unsafe.Pointer(&a))) fmt.Printf("b: %+v\n", *(*reflect.SliceHeader)(unsafe.Pointer(&b))) fmt.Printf("c: %+v", *(*reflect.SliceHeader)(unsafe.Pointer(&c))) ~~~~~~~~~~~~~~~~~~~结果:~~~~~~~~~~~~~~~~~~~~~~~~~~ a: {Data:0 Len:0 Cap:0} b: {Data:824635080432 Len:0 Cap:0} c: {Data:824635080432 Len:0 Cap:0} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
字符串转成byte数组,会发生内存拷贝吗?
会发生内存拷贝,在go中所有的类型强转都会发生内存拷贝.如果出现频繁的内存拷贝显然性能会受到影响,那怎么才能不发生内存拷贝呢?只需要把 StringHeader
的地址强转成 SliceHeader
就行:
a := "aaa" aa := *(*reflect.StringHeader)(unsafe.Pointer(&a)) // 获取a的底层结构 sa := *(*[]byte)(unsafe.Pointer(&aa))
翻转含有中文、数字、英文字母的字符串
可以通过go的内置类型rune(int32)实现:
s := "中国zhongguo123加油" rs := []rune(s) var res []rune for i := len(rs) - 1; i >= 0; i-- { res = append(res, rs[i]) } fmt.Println(string(res)) ~~~~~~~~~~~~结果:~~~~~~~~~~~~~~~~~ 油加321ouggnohz国中 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
拷贝大切片一定比小切片代价大吗?
不是,切片在拷贝时都是相同大小的.切片拷贝本质上只是拷贝了切片的底层结构,由三个字段组成:Data,Len,Cap
type SliceHeader struct { Data uintptr Len int Cap int }
对未初始化的的chan进行读写,会怎么样?为什么?
会发生deadlock错误.
当往未初始化的chan中写数据时(源码如下),如果未阻塞,则直接返回false,表示写入失败,如果能够阻塞,则通过throw抛出错误;
当读取未初始化的chan时(源码如下):
json包变量不加tag会怎么样
- 如果结果体中字段首写字母是小写,则该字段为私有字段,无法转换(a);
- 如果首写字母大写且无tag,可以转换,并且转换后的字段名和原字段名一致(B);
- 如果首写字母大写且有tag,可以转换,转换后字段名为tag中指定的名称(C).
type test struct { a string B string C string `json:"CC"` } t := test{ a: "a", B: "b", C: "c", }
jsonT, _ := json.Marshal(t) fmt.Println(string(jsonT)) ~~~~~~~~~~~~~结果:~~~~~~~~~~~~~~~~~ {"B":"b","CC":"c"} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
切片深浅拷贝
浅拷贝复制的是指针,而指针指向的值只有一份,go中浅拷贝就是slice赋值操作;深拷贝复制的是指针指向的值,通过copy方法实现:
a1 := []int{1, 2, 3, 4} b := a1 fmt.Println("a1:", a1) b[0] = 11 fmt.Println("浅拷贝: ", a1) a2 := []int{11, 22, 33, 44} fmt.Println("a2: ", a2) var c = make([]int, len(a2)) copy(c, a2) c[0] = 0 fmt.Println("深拷贝: ", a2)
~~~~~~~~~~~~~结果:~~~~~~~~~~~~~~ a1: [1 2 3 4] 浅拷贝: [11 2 3 4] a2: [11 22 33 44] 深拷贝: [11 22 33 44] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make和new的区别
make和new都用于内存分配.make只能用于map,slice,channel的内存分配,new返回的是指向Type的指针, make直接返回的是Type类型值.
func make(t Type, size ...IntegerType) Type func new(Type) *Type
Go 语言的局部变量分配在栈上还是堆上?
go语言编译器会做逃逸分析,分析局部变量的作用域是否逃出了函数的作用域,要是没有就放到栈上,要是超出了函数的作用域就自动放到堆上。 注意: 当使用fmt.println函数时,局部变量的作用域会超出函数的作用域,所以局部变量是在堆上。而println是内联函数,并没有使局部变量的作用域逃出函数的作用域,所以是在栈上。程序强制停止信号捕获
当强制停止程序时,如使用ctrl+c停止一个程序时,可以通过os和os/signal进行捕获:var ch = make(chan os.Signal) signal.Notify(ch, os.Interrupt) // 主程序 go func() { for { select { case ss := <-ch: fmt.Println(ss) } } }()
两个interface能进行比较吗
可以.interface中包含两个字段,类型(T)和值(V),两个interface相等必须满足T和V都相等.
type tes struct { name string } type tester interface{} var ( t1, t2 tester = &tes{"Tom"}, &tes{"Tom"} t3, t4 tester = tes{"Tom"}, tes{"Tom"} ) println(t1 == t2) // false println(t3 == t4) // true
t1和t2的类型都是*tes,但是其值分别为t1和t2的地址,两个地址是不同的,所以false;
t3和t4的类型都是tes,值是tes结构体,并且name字段对应的值都是"Tom",所以true.
标签:知识点,int,make,汇总,Golang,拷贝,tes,fmt,切片 来源: https://www.cnblogs.com/wangtaobiu/p/16248763.html