go语言基础学习二

结构体打印时,%v 和 %+v 的区别#

1、%v 打印结构体时,只会打印字段的值 2、%+v 打印结构体时,会打印字段的名称和值 3、%+v 打印结构体时,会打印字段的名称和值,同时会打印结构体的类型



//示例代码:
package main
import "fmt"

type User struct {
	ID   int
	Name string
}

func main() {
	u := User{1, "test"}
	fmt.Printf("%v\n", u)   // {1 test}  仅值
	fmt.Printf("%+v\n", u) // {ID:1 Name:test} 字段名+值
	fmt.Printf("%#v\n", u) // main.User{ID:1, Name:"test"} 类型+字段名+值
}
	

Go 语言中如何表示枚举值(enums)?#

在常量中用iota可以表示枚举。iota从0开始



const (
        B = 1 << (10 * iota)
        KiB 
        MiB
        GiB
        TiB
        PiB
        EiB
)

空 struct{} 的用途#

1,用map模拟一个set,那么就要把值置为struct{},struct{}本身不占任何空间,可以避免任何多余的内存分配。



import "fmt"

type Set map[string]struct{}

func main() {
	set := make(Set)

	for _, item := range []string{"A", "A", "B", "C"} {
		set[item] = struct{}{}//struct{} 是一个类型(空结构体类型),struct{}{} 是一个值(空结构体的零值)
	}
	fmt.Println(len(set)) // 3
	if _, ok := set["A"]; ok {
		fmt.Println("A exists") // A exists
	}
}

2,有时候给通道发送一个空结构体,channel<-struct{}{},也是节省了空间



func main() {
// 创建缓冲为 1 的通道,元素类型是空结构体 struct{}
ch := make(chan struct{}, 1)

// 启动一个协程
go func() {
<-ch   // 阻塞:等待从通道接收信号
// do something 收到信号后才执行逻辑
}()

ch <- struct{}{} // 向通道发送一个信号
}

3、仅有方法的结构体



type Lamp struct{}

go里面的int和int32是同一个概念吗?#

不是一个概念。

go语言中的int的大小是和操作系统位数相关的,如果是32位操作系统,int类型的大小就是4字节。如果是64位操作系统,int类型的大小就是8个字节

而int后有数字的话,占用空间大小是固定的:int8占1个字节,int16占2个字节,int32占4个字节,int64占8个字节。

init() 函数是什么时候执行的?#

简答: 在main函数之前执行。

执行顺序:import –> const –> var –>init()–>main()

一个文件可以有多个init()函数,同一文件内执行顺序:从上到下,按代码书写顺序依次执行,无入参、无返回值、自动执行

如何知道一个对象是分配在栈上还是堆上?#

Go的逃逸分析是在编译器完成的;go局部变量会进行逃逸分析。如果变量离开作用域后没有被引用,则优先分配到栈上,否则分配到堆上 关于逃逸的可能:如果变量内存占用较大时,优先放在堆上;如果函数外部没有引用,优先放在栈中;

go build -gcflags '-m -m -l' xxx.go 该命令可以辅助查看逃逸分析结果