- 包声明
- 包引入
- 函数
- 变量
- 语句&表达式
- 注释
/* 定义包名 */
package main
/* 告诉go,需要fmt(格式化I/O)包 */
import "fmt"
/* 入口函数 */
func main() {
fmt.Println("Hello, World!")
}
//执行go
go run hello.go //Hello, World!
基础语法
- Go标记(关键字,标识符,常量,字符串,符号)
- 行分割符(Go自动每行加分号)
- 注释,标识符,关键字,同JS
-
Go空格(变量声明必须用空格隔开)
fruit = apple + banana
数据类型
- 布尔型:true,false
- 数字型:int,float
- 字符串型:UTF-8标识Unicode文本
- 派生型
- 指针型(Pointer)
- 数组型
- 结构化型(struct)
- Channel类型
- 函数类型
- 切片类型
- 接口类型(interface)
- Map类型
-
变量声明
//指定变量类型,默认赋值 var v_name v_type //根据值自动判断类型 var v_name = value //省略var,:=左侧变量必须是未声明的 v_name := value var a int = 10 var b = 10 c := 10
- 多变量声明
var v1 , v2 , v3 type var v1 , v2 , v3 = a , b ,c v1 , v2 , v3 := a , b ,c //一般因式分解关键字的写法用于全局变量声明 var ( vname1 v_type1 vname2 v_type2 ) ckage main
var x, y int
var ( // 这种因式分解关键字的写法一般用于声明全局变量
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"
func main(){
g, h := 123, "hello"
println(x, y, a, b, c, d, e, f, g, h)
}
- 值类型( int、float、bool 和 string)和引用类型
- 常量
const indentifer [type] = vlaue
const c_name1, c_name2 = value1, value2
package main
import "fmt"
func main() {
const LENGTH int = 10
const WIDTH int = 5
var area int
const a, b, c = 1, false, "str" //多重赋值
area = LENGTH * WIDTH
fmt.Printf("面积为 : %d", area)
println()
println(a, b, c)
}
- iota : 特殊常量,可被编译器修改;可被用作枚举值
const (
a = iota
b = iotb
c = iotc
)
//same as
const (
a = iota
b
c
)
## 运算符及优先级同JS
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 其他运算符
## 条件与循环(类JS)
if boolean_exp {
/ ... /
}
for a := 0; a < 10; a++ {
fmt.Printf("a 的值为: %d\n", a)
}
## 函数(至少一个main函数)
func function_name( [parameter list] ) [return_types] {
//...
}
package main
import "fmt"
func main() {
/ 定义局部变量 /
var a int = 100
var b int = 200
var ret int
/ 调用函数并返回最大值 /
ret = max(a, b)
fmt.Printf( "最大值是 : %d\n", ret )
}
/ 函数返回两个数的最大值 /
func max(num1, num2 int) int {
/ 定义局部变量 /
var result int
if (num1 > num2) {
result = num1
} else {
result = num2
}
return result
}
### 函数参数
- 值传递:函数调用时将实际参数复制一份到函数,二者相互独立
- 引用传递:函数调用时将实际参数的地址传递到函数,二者相互影响
### 函数用法
- 作为值
- 闭包
- 方法
## 变量作用域
### 三种变量类型
- 局部变量:在函数内定义
- 全局变量:在函数外定义
- 形参:函数定义中的变量
### 初始化局部和全局变量
``` int,float32 均为0;pointer为nil```
## 数组
### 声明
var variable_name [SIZE] variable_type
//examples
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
### 访问成员(同JS)
## 指针
> 旨在简单执行一些任务,变量是一种使用方便的占位符,用于内存地址引用
一个指针变量可以指向任何一个值的内存地址,使用指针前要声明
package main
import "fmt"
func main() {
var a int= 20 / 声明实际变量 /
var ip int / 1.声明指针变量 */
ip = &a / 2. 为指针变量赋值,指针变量的存储地址 /
fmt.Printf("a 变量的地址是: %x\n", &a )
/ 指针变量的存储地址 /
fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
/ 3. 访问指针变量中指向地址的值,使用指针访问值 /
fmt.Printf("ip 变量的值: %d\n", ip )
}
- Go空指针:当一个指针被定义后没有分配到任何变量时,它的值为 nil。
## 结构体
> 数组可以存储同一类型的数据,但结构体中可以定义不同类型数据。结构体即一些列同或异类型
的数据构成的集合。
### 定义
type struct_variable_type struct {
member definition;
member definition;
...
member definition;
}
//旦定义了结构体类型,它就能用于变量的声明
variable_name := structure_variable_type {value1, value2...valuen}
//访问用.语法
## 切片(slice)
> 切片是对数组的抽象,Go提供了一种灵活强悍的内置类型切片
//定义切片
var identifier []type
//初始化
s :=[] int {1,2,3 }
//使用make()函数来创建切片:
slice1 := make([]type, len)
## Range
> 用于for循环中迭代数组(array)、切片(slice)、链表(channel)或集合(map)的元素
package main
import "fmt"
func main() {
//这是我们使用range去求一个slice的和。使用数组跟这个很类似
nums := []int{2, 3, 4}
sum := 0
for , 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)
}
}
//输出
sum: 9
index: 1
a -> apple
b -> banana
0 103
1 111
## Map集合
> 无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,
我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。
/ 声明变量,默认 map 是 nil /
var map_variable map[key_data_type]value_data_type
/ 使用 make 函数 /
map_variable = make(map[key_data_type]value_data_type)
## 递归函数
package main
import "fmt"
func Factorial(x int) (result int) {
if x == 0 {
result = 1;
} else {
result = x * Factorial(x - 1);
}
return;
}
func main() {
var i int = 15
fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(i))
}
## 类型转换
type_name(expression)
package main
import "fmt"
func main() {
var sum int = 17
var count int = 5
var mean float32
mean = float32(sum)/float32(count)
fmt.Printf("mean 的值为: %f\n",mean)
}
// 3.400000
## 接口
> Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
/ 定义接口 /
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}
/ 定义结构体 /
type struct_name struct {
/ variables /
}
/ 实现接口方法 /
func (struct_name_variable struct_name) method_name1() [return_type] {
/ 方法实现 /
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
/ 方法实现/
}
package main
import (
"fmt"
)
type Phone interface {
call()
}
type NokiaPhone struct {
}
func (nokiaPhone NokiaPhone) call() {
fmt.Println("I am Nokia, I can call you!")
}
type IPhone struct {
}
func (iPhone IPhone) call() {
fmt.Println("I am iPhone, I can call you!")
}
func main() {
var phone Phone
phone = new(NokiaPhone)
phone.call()
phone = new(IPhone)
phone.call()
}
## 错误处理
type error interface {
Error() string
}