把我学习的笔记记录下来,教程资源: https://www.kancloud.cn/kancloud/the-way-to-go/72679
- go 一行作为一条语句,不建议用分号
- go语言类似ts,包含javasript语法,同时又支持面向对象特性,但又有c语言的指针、结构体,也有python的语法
- 变量声名后不用new 关键字,结构体也是不用new,用var声名后直接拿来用
变量声名:
var a,b,c int var a int = 0 var (a, int b, string ) c : = 10//快速声名
- go语言条件判断时没有小括号
- go语言必须有一个main入口,必须声名package,且不同文件如果同属一个package,则被视为多个文件属于一个模块
函数类似javascript,声名函数必须以func 声名,函数可以有返回结果的类型声名,可以直接返回多个结果,用到了数据的自动封装和自动解封,如下
package main import "fmt" func swap(x, y string) (string, string) { return y, x } func main() { a, b := swap("Mahesh", "Kumar") fmt.Println(a, b) }
- 支持地址引用,&变量名,如参数中的引用传递,而不是值传递: &var1,而非var1
支持函数和方法,方法就是可以给一个类型设置一个函数,也可以动态的设置,即使类型没有定义该方法,如下:
package main import ( "fmt" ) /* 定义函数 */ type Circle struct { radius float64 } func main() { var c1 Circle c1.radius = 10.00 fmt.Println("Area of Circle(c1) = ", c1.getArea()) } //该 method 属于 Circle 类型对象中的方法 func (c Circle) getArea() float64 { //c.radius 即为 Circle 类型对象中的属性 return 3.14 * c.radius * c.radius }
声名数组
var a []int var b = [3]int{1,2,3} var c = [...]int{1,2,3}
地址和指针
&表示一个变量的地址
*表示根据地址去取值
var a *int a的结果为0
指针通常用ptr来定义
nil表示空指针:if(ptr != nil)/* ptr 不是空指针 */
函数中如果传入的是地址,接受的则是指针,如a(%var1),则定义的时候是func a(var1 *type1){}结构体
什么是结构体?Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型
用type声名type Books struct { title string author string subject string book_id int } func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ var Book2 Books /* 声明 Book2 为 Books 类型 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495 }
函数形参使用指针和结构体
func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ var Book2 Books /* 声明 Book2 为 Books 类型 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495 /* 打印 Book1 信息 */ printBook(&Book1) } func printBook( book *Books ) { fmt.Printf( "Book title : %s\n", book.title); }
切片
什么是切片?切片就是动态数组
如何声名?有两种方式,一种是类似数组声名,不指定长度即可,还有一种是make方法,需要传递三个参数,make([]int, 3,5)默认长度为3, 最大长度只能到达5(容量,可选参数),即动态的长度可加长两位,个人理解是这样,但是测试发现5这个容量貌似无效
截取切片:numbers := []int{0,1,2,3,4,5,6,7,8},从1到4,不包含4:numbers[1:4]
往切片中添加新元素,append(numbers, 0, 1),copy表示可以拷贝一个切片到另外一个切片中,用法:copy(dest, src),把src拷贝到test中map
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type简单来写就是 m1 := make(map[string]string)
赋值,直接赋值,m1[aa] = “nn”;
删除值:delete(m1, aa)range
迭代数组、切片、map、通道、集合
for用法: for index, num = range nums{}类型转换
type_name(expression),如 func main() { var sum int = 17 var count int = 5 var mean float32 mean = float32(sum)/float32(count) fmt.Printf("mean 的值为: %f\n",mean) }
接口
定义接口:type type interface_name interface {}
定义结构体: type struct_name struct {}
接口实现: func (struct_name_variable struct_name) method_name1() [return_type] {}
用法:直接定义一个普通的函数,但是这个函数支持接收这者,即在方法前面制定接收这个函数的变量,一般来说是结构体,然后接口就可以直接调用这个函数
注意:这里面怎么把结构体作为接口的实现呢?需要把接口、结构体、实现三者结合起来,接口把实现给了结构体,然后自己再去调用,要用到new 关键字func main() { var phone Phone//接口,只有call方法type Phone interface { call()} phone = new(NokiaPhone)//NokiaPhone为一个空的结构体 phone.call() phone = new(IPhone) phone.call() }
错误处理
- 错误是个接口
- 定义结构体,并定义错误方法的实现,然后用结构体去调用错误方法
go项目目录结构说明
src文件夹:每个次级文件夹(如demo)就是代表一个go项目,里面存放源程序
bin文件夹:go的每个项目生成的二进制可执行程序。windows下会生成.exe文件,linux下会生成可执行文件。Go的最大特色之一就是可移植性,就是说,当生成一个demo.exe之后,将这个exe文件放在任意一台windows系统上(即使没有安装go安装包),也是可以执行的。这是让PHP,Python等脚本语言望成莫及的。
pkg文件夹:第三方库。里面存放你的项目中引用的第三方库(非官方已经提供的库)
eclipse 中开发go项目
- eclipse go环境安装:http://www.jianshu.com/p/48025776632c
- 项目要指定
gopath
,建议项目直接放在gopath/src
下。可直接从gopath/src
路径中导入开源的项目,同时也包括自己的项目。可把gopath/src
当做工作空间。
eclipse 中调试
rumtime.BreakPoint
+ fmt.Print
go test
- go 测试以包为单位
- 如果想测试单个文件,则需要不存在依赖 go test 如果有依赖,则必须以包为单位测试
- go test -v 输出详细信息