1. 在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分,但在实际开发中我们并不鼓励这种做法。
2. 变量声明
a. 第一种,指定变量类型,如果没有初始化,则变量默认为零值。
var v_name v_type
v_name = value
b. 第二种,根据值自行判定变量类型。
var v_name = value
c. 第三种,省略 var, 注意 := 左侧如果没有声明新的变量,就产生编译错误,格式:
v_name := value
eg: var intVal int
intVal :=1 // 这时候会产生编译错误
intVal,intVal1 := 1,2 // 此时不会产生编译错误,因为有声明新的变量,因为 := 是一个声明语句
3. 多变量声明
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
var vname1, vname2, vname3 = v1, v2, v3 // 和 python 很像,不需要显示声明类型,自动推断
vname1, vname2, vname3 := v1, v2, v3 // 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误
// 这种因式分解关键字的写法一般用于声明全局变量
var (
vname1 v_type1
vname2 v_type2
)
4. 常量
const identifier [type] = value
可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。
显式类型定义: const b string = "abc"
隐式类型定义: const b = "abc"
iota,特殊常量 ,iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引);
eg: package main
import "fmt"
func main() {
const (
a = iota //0
b //1
c //2
d = "ha" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
结果:0 1 2 ha ha 100 100 7 8
5.函数
func function_name( [parameter list] ) [return_types] {
函数体
}
函数定义解析:
func:函数由 func 开始声明
function_name:函数名称,函数名和参数列表一起构成了函数签名。
parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
eturn_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
函数体:函数定义的代码集合。
func max(num1, num2 int) int {
/* 声明局部变量 */
var result int
if (num1 > num2) {
result = num1
} else {
result = num2
}
return result
}
6. 指针
Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。
eg:package main
import "fmt"
func main() {
var a int = 10
fmt.Printf("变量的地址: %x ", &a
}
一个指针变量指向了一个值的内存地址。类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:
var var_name *var-type
var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针;
指针使用流程:
定义指针变量。
为指针变量赋值。
访问指针变量中指向地址的值
在指针类型前面加上 * 号(前缀)来获取指针所指向的内容
指针是通过地址值来获取所指向的内容
eg:package main
import "fmt"
func main() {
var a int= 20 /* 声明实际变量 */
var ip *int /* 声明指针变量 */
ip = &a /* 指针变量的存储地址 */
fmt.Printf("a 变量的地址是: %x ", &a )
/* 指针变量的存储地址 */
fmt.Printf("ip 变量储存的指针地址: %x ", ip )
/* 使用指针访问值 */
fmt.Printf("*ip 变量的值: %d ", *ip )
}
空指针:当一个指针被定义后没有分配到任何变量时,它的值为 nil。
nil 指针也称为空指针。
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。
一个指针变量通常缩写为 ptr。
7、结构体
结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
type struct_variable_type struct {
member definition
member definition
...
member definition
}
一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:
variable_name := structure_variable_type {value1, value2...valuen}
或
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
如果要访问结构体成员,需要使用点号 . 操作符,格式为:
结构体.成员名"
eg:
package main
import "fmt"
type Books struct {
title string
author string
subject string
book_id int
}
func main() {
var Book1 Books /* 声明 Book1 为 Books 类型 */
var Book2 Books /* 声明 Book2 为 Books 类型 */
/* book 1 描述 */
Book1.title = "Go 语言"
Book1.author = "www.runoob.com"
Book1.subject = "Go 语言教程"
Book1.book_id = 6495407
/* book 2 描述 */
Book2.title = "Python 教程"
Book2.author = "www.runoob.com"
Book2.subject = "Python 语言教程"
Book2.book_id = 6495700
/* 打印 Book1 信息 */
fmt.Printf( "Book 1 title : %s ", Book1.title)
fmt.Printf( "Book 1 author : %s ", Book1.author)
fmt.Printf( "Book 1 subject : %s ", Book1.subject)
fmt.Printf( "Book 1 book_id : %d ", Book1.book_id)
/* 打印 Book2 信息 */
fmt.Printf( "Book 2 title : %s ", Book2.title)
fmt.Printf( "Book 2 author : %s ", Book2.author)
fmt.Printf( "Book 2 subject : %s ", Book2.subject)
fmt.Printf( "Book 2 book_id : %d ", Book2.book_id)
printBook(&Book1)
printBook(&Book2)
}
func printBook( book *Books ) {
fmt.Printf( "Book title : %s ", book.title)
fmt.Printf( "Book author : %s ", book.author)
fmt.Printf( "Book subject : %s ", book.subject)
fmt.Printf( "Book book_id : %d ", book.book_id)
}
8. 切片
Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
var identifier []type
var slice1 []type = make([]type, len)
也可以简写为
slice1 := make([]type, len)
make([]T, length, capacity)
这里 len 是数组的长度并且也是切片的初始长度。、
切片设置上限和下限:slice[lower-bound:upper-bound]
append()、copy()函数
9. printf 转换字符
%d 十进制整数
%x, %o, %b 十六进制,八进制,二进制整数。
%f, %g, %e 浮点数: 3.141593 3.141592653589793 3.141593e+00
%t 布尔:true或false
%c 字符(rune) (Unicode码点)
%s 字符串
%q 带双引号的字符串"abc"或带单引号的字符'c'
%v 变量的自然形式(natural format)
%T 变量的类型
%% 字面上的百分号标志(无操作数)
10. 驼峰式命名规则:
单词之间不以空格、连接号或者底线连结(例如不应写成:camel case、camel-case或camel_case形式)。共有两种格式:
1、小驼峰式命名法(lower camel case):
第一个单词以小写字母开始,第二个单词的首字母大写。例如:firstName、lastName。
2、大驼峰式命名法(upper camel case):
每一个单词的首字母都采用大写字母,例如:FirstName、LastName、CamelCase,也被称为 Pascal 命名法。
变种:StudlyCaps,是“驼峰式大小写”的变种。
补充说明,在JAVA中:类名的标识符一般用大驼峰式书写格式,方法和变量的标识符则多用小驼峰式书写格式。
11. Go语言主要有四种类型的声明语句:var、const、type和func,分别对应变量、常量、类型和函数实体对象的声明。