来自于
runoob-go语言教程的一些总结
刚开始学习go语言,估计会有一些问题,欢迎大家指出我的问题或理解上的不对
目录:
第一个程序
变量
函数
数组
指针
结构体
接口
切片
范围(range)
Map
错误处理
第一个程序
package main
import "fmt"
func main () {/* 这是我的第一个简单的程序 */fmt . Println ( "Hello, World!" )}
第一行package main定义包名import "fmt"表示需要fmt包func main()为程序开始执行的函数,每个可执行程序都包含main函数。
标识符(常量、变量、类型、函数名等等)以大写字母开头,其对应对象就是public的,若以小写字母开头,则是protected的
变量:
定义变量为var name type,如 var a int,默认赋值也有var a = 10,更多是使用 a := 10,这类似于c++里使用auto 定义和初始化局部变量:不允许出现未使用的局部变量全局变量:允许不使用,且被import到别的包时,可以被调用
函数:
模式为:func function_name( [parameter list] ) [return_types] {function_body}
例子:func swap(a string, b string) (string, string) {return b, a}该模式为值传递,引用传递为(以上面的swap为例):func swap(a *string, b *string) {var temp stringtemp = *a*a = *b*b = temp}其用法与c++中指针传递类似,暂时没有发现与c++中引用传递相似的语句
数组:
声明数组:var variable_name[SIZE] variable_type例子:var balance [10] float32初始化数组:var balance = [5] float32{1000.0, 2.0, 3.4, 7.0, 50.0}var balance = [] int{1,2,3}读取写入数组都可通过下标索引,下标从0开始:balance[4] = 50
多维数组:var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type例子:var threedim [5][10][4] int初始化:a = [ 3 ][ 4 ] int {{ 0 , 1 , 2 , 3 } , /* 第一行索引为 0 */{ 4 , 5 , 6 , 7 } , /* 第二行索引为 1 */{ 8 , 9 , 10 , 11 } /* 第三行索引为 2 */}访问:val = a[2][3]
数组作为函数参数:形参可设定数组大小,也可不设定func getAverage ( arr [] int , size int ) float32 {}
指针:
*和&用法与c++类似,&取址,*获取地址对应数值例子:var ip *intvar a int = 20支持指针数组[10]*int,支持指向指针的指针**int,var a intvar ptr *intvar pptr **int
a = 3000
/* 指针 ptr 地址 */ptr = &a
/* 指向指针 ptr 地址 */pptr = &ptr
/* 获取 pptr 的值 */fmt.Printf("变量 a = %d\n", a ) //3000fmt.Printf("指针变量 *ptr = %d\n", *ptr ) //3000fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr) //3000
向函数传递指针:如之前的函数部分的swap
结构体:
定义结构体:type struct_variable_type struct {member definition;member definition;...}用于变量声明:variable_name := structure_variable_type {value1, value2...valuen}
访问结构体:访问结构体成员用"."例子:type Books struct {title stringauthor stringsubject stringbook_id int}var Book1 Books /* 声明 Book1 为 Books 类型 */var Book2 Books /* 声明 Book2 为 Books 类型 */
/* book 1 描述 */Book1.title = "Go 语言"Book1.author = "www"Book1.subject = "Go 教程"Book1.book_id = 123456
结构体指针:与之前类似,不过使用结构体指针访问结构体成员也使用"."操作符例子:var struct_pointer *Booksstruct_pointer = &Book1struct_pointer.title
接口:
我觉得go像是将原来类的概念中的成员变量和成员函数分开放了,成员变量放在结构体中,成员函数放在了接口中,其实现大约是:
- 定义接口
- 定义并实现函数,为函数指定对应的接收者(接收者可以是命名类型或结构体类型的一个值或一个指针。所有给定类型的方法属于该类型的方法集)
- 见http://www.runoob.com/go/go-method.html)
见例子:
切片:
范围 (range):用于达到动态数组的目的内置类型支持与python切片类似方式,也可调用内置函数make([]type, length, capacity)生成默认切片;对数组的切片,是原数组的引用(与python不同),切片为空则为"nil",长度为0;
append()方法:var numbers []intprintSlice(numbers)
/* 允许追加空切片 */numbers = append(numbers, 0)printSlice(numbers)
/* 向切片添加一个元素 */numbers = append(numbers, 1)printSlice(numbers)
/* 同时添加多个元素 */numbers = append(numbers, 2,3,4)printSlice(numbers)
/* 创建切片 numbers1 是之前切片的两倍容量*/numbers1 := make([]int, len(numbers), (cap(numbers))*2)
/* 拷贝 numbers 的内容到 numbers1 */copy(numbers1,numbers)printSlice(numbers1)
func printSlice(x []int){fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)}运行结果len=0 cap=0 slice=[]len=1 cap=1 slice=[0]len=2 cap=2 slice=[0 1]len=5 cap=6 slice=[0 1 2 3 4]len=5 cap=12 slice=[0 1 2 3 4]
用于for循环中迭代。数组和切片返回索引值,集合返回key-value对的key。例子:package mainimport "fmt"func main() {//这是我们使用range去求一个slice的和。使用数组跟这个很类似nums := []int{2, 3, 4}sum := 0for _, num := range nums {sum += num}fmt.Println("sum:", sum)//在数组上使用range将传入index和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。for i, num := range nums {if num == 3 {fmt.Println("index:", i)}}//range也可以用在map的键值对上。kvs := map[string]string{"a": "apple", "b": "banana"}for k, v := range kvs {fmt.Printf("%s -> %s\n", k, v)}//range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。for i, c := range "go" {fmt.Println(i, c)}}
Map:
定义map:可以使用内建函数make,也可以使用map关键字:/* 声明变量,默认 map 是 nil */var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */map_variable := make(map[key_data_type]value_data_type)
使用:value, status = onemap[key]status为查找状态delete():从map中根据key删除对应k-v对delete(onemap, key)
强制类型转换:var sum int = 17var count int = 5var mean float32mean = float32(sum)/float32(count) //3.400000
错误处理:
通过实现error接口来生成错误信息见例子: