go语法专题:命令,defer,interface{},指针与引用,变量和指针,fmt,new和make

 go语言命令

#go 基本命令
go env #查看goroot,gopath,gocache,version...
go env -w GOPROXY=https://goproxy.io,direct
go env -w GOPATH=C:\Users\kuangzheng\go;D:\codeResource\hellogo #windos设置失败可打开修改环境变量:rundll32 sysdm.cpl,EditEnvironmentVariables
go env -w GOPROXY=https://goproxy.cn,direct GOPATH
=C:\Users\kuangzheng\go go run #执行go程序,必须是main包 go build #编译成二进制文件 go get # go list #列出包和模块 go mod #模块管理,待理解 go install #编译和安装包和依赖 #gofmt 命令 gofmt [flags] [path ...] gofmt -e ./ #go tool 命令 go tool compile [flags] file... go tool fix [-r name,...] [path ...] go test -trace trace.out pkg go tool trace trace.out

 

defer(延迟执行语句)

参考:http://c.biancheng.net/view/61.html

 

interface和interface{}的区别

参考:https://www.cnblogs.com/maji233/p/11178413.html(理解interface和interface{})

 

指针与引用

参考:https://www.cnblogs.com/anthony-dong/p/12249394.html(指针与引用)

 

golang中值类型变量和指针类型变量的区别总结

参考:https://studygolang.com/articles/11918

 

fmt格式化函数

1,格式化输出和读取

Print, Printf, Println #输出到 标准化输出
Sprint, Sprintf, Sprintln #输出为 一个字符串
Fprint, Fprintf, Fprintln #写入到 一个io.Writer

Scan, Scanf, Scanln #从 标准化输入 读取
Sscan, Sscanf, Sscanln #从一个字符串 读取
Fscan, Fscanf, Fscanln #从一个io.Reader 读取

...f结尾可以格式化
...ln结尾:每个参数间有空格,语句结束会添加换行

2,格式化参数列表

 参考:https://www.jianshu.com/p/f54baf75eedf

//通用
%v        值的默认格式
%+v       类似%v,但输出结构体时会添加字段名
%#v    Go语法表示值
%T     Go语法表示类型
%%       百分号表示
布尔
%t  true或false 
整数
%b  表示二进制
%d  表示十进制
%o  表示八进制
%q  该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x  表示为十六进制,使用a-f
%X  表示为十六进制,使用A-F
%c  该值对应的unicode吗值
%U  表示为Unicode格式:U+1234,等价于"U+%04X"
浮点和复数
%b  无小数部分、二进制指数的科学计数法,如-123456p-78;参见strconv.FormatFloat
%e  科学计数法,例如 -1234.456e+78 
%E  科学计数法,例如 -1234.456E+78
%f  有小数点而无指数,例如 123.456 
%F  等价于%f
%g  根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
%G  根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)
字符串和[]byte
%s  输出字符串表示(string类型或[]byte) 
%q  双引号围绕的字符串,由Go语法安全地转义
%x  十六进制,小写字母,每字节两个字符 (使用a-f)
%X  十六进制,大写字母,每字节两个字符 (使用A-F) 
指针,切片
%p       切片第一个元素的指针,十六进制内存地址,前缀ox

3,buffer是用来从存储写入内容的,stream是用来存储读取的内容的

r := strings.NewReader("some io.Reader stream to be read\n")

var buf1, buf2 bytes.Buffer
w := io.MultiWriter(&buf1, &buf2)

if _, err := io.Copy(w, r); err != nil {
    log.Fatal(err)
}
fmt.Print(buf1.String())
fmt.Print(buf2.String())

 

make和new的区别

参考:https://www.jb51.net/article/126703.htm

1,make和new都是golang用来分配内存的內建函数,且在堆上分配内存,make 即分配内存,也初始化内存。new只是将内存清零,并没有初始化内存。

2,make返回的还是引用类型本身;而new返回的是指向类型的指针。

3,make只能用来分配及初始化类型为slice,map,channel的数据;new可以分配任意类型的数据。

变量的申明

var i int
var s string

var j *int
*j=10  //会报错

var k *int
k=new(int) //分配内存
*k=10 //正确

对于引用类型的变量,我们不光要声明它,还要为它分配内容空间,否则我们的值放在哪里去呢?这就是上面错误提示的原因。

对于值类型的声明不需要,是因为已经默认帮我们分配好了。

new

它只接受一个参数,这个参数是一个类型,分配好内存后,返回一个指向该类型内存地址的指针。同时请注意它同时把分配的内存置为零,也就是类型的零值。

我们的例子中,如果没有*i=10,那么打印的就是0。这里体现不出来new函数这种内存置为零的好处,我们再看一个例子。

func main() {
 u:=new(user)
 u.lock.Lock()
 u.name = "张三"
 u.lock.Unlock()
 fmt.Println(u)
}
type user struct {
 lock sync.Mutex
 name string
 age int
}

示例中的user类型中的lock字段我不用初始化,直接可以拿来用,不会有无效内存引用异常,因为它已经被零值了。

1,这就是new,它返回的永远是类型的指针,指向分配类型的内存地址。

2,new并不常用,通常都是采用短语句声明以及结构体的字面量达到我们的目的,比如:

i:=0
u:=user{}

make

make也是用于内存分配的,但是和new不同,它只用于chan、map以及切片的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。

注意,因为这三种类型是引用类型,所以必须得初始化,但是不是置为零值,这个和new是不一样的。

make返回的还是这三个引用类型本身;而new返回的是指向类型的指针。

 

posted @ 2021-07-02 11:31  小匡程序员  阅读(155)  评论(0编辑  收藏  举报