一、基本结构和基本数据类型
1、 文件名、关键字与标识符
文件名均由小写字母组成,如 scanner.go
有效的标识符必须以字符(可以使用任何 UTF-8 编码的字符或 _ )开头,然后紧跟着 0 个或多个字符或 Unicode 数字,如:X56、group1、_x23、i、өԑ12。
_ 本身就是一个特殊的标识符,被称为空白标识符。
25 个关键字或保留字 | default | func | interface | select | break | | —- | —- | —- | —- | —- | | case | defer | go | map | struct | | chan | else | goto | package | switch | | const | fallthrough | if | range | type | | continue | for | import | return | var |
- 36 个预定义标识符
2、包的概念、导入与可见性
package main 表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。
一个 Go 程序是通过 import 关键字将一组包链接在一起。 ``` import “fmt” import “os”
或者
import ( “fmt” “os” )
-
可见性规则
- 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头的标识符的对象就可以被外部包的代码所使用(像面向对象语言中的 public)
- 标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )
-
使用包的别名来解决包名之间的名称冲突
import fm “fmt”
<a name="e34d9b42"></a>
### 3、函数
-
函数规范
func functionName(parameter_list) (return_value_list) { … }
parameter_list 的形式为 (param1 type1, param2 type2, …)
return_value_list 的形式为 (ret1 type1, ret2 type2, …)
example
func add(a int, b int) (c int,b1 int){ return a + b,b } var c,b1 = add(2,3)
<a name="f457ab45"></a>
### 4、注释
// 开头的单行注释 /**/多行注释
<a name="a972cfba"></a>
### 5、类型
- 基本类型,如:int、float、bool、string;
- 结构化的(复合的),如:struct、array、slice、map、channel;
- 只描述类型的行为的,如:interface
<a name="a4c4d2f5"></a>
### 6、Go 程序的一般结构
- Go 程序的执行(程序启动)顺序如下:
- 按顺序导入所有被 main 包引用的其它包,然后在每个包中执行如下流程:
- 如果该包又导入了其它的包,则从第一步开始递归执行,但是每个包只会被导入一次。
- 然后以相反的顺序在每个包中初始化常量和变量,如果该包含有 init 函数的话,则调用该函数。
- 在完成这一切之后,main 也执行同样的过程,最后调用 main 函数开始执行程序。
package main
import ( “fmt” )
const c = “C”
var v int = 5
type T struct{}
func init() { // initialization of package } func main() { var a int Func1() // … fmt.Println(a) }
//这是啥 func (t T) Method1() { //… } func Func1() { // exported function Func1 //… }
<a name="52629000"></a>
### 7、类型转换
valueOfTypeB = typeB(valueOfTypeA)
:= 声明变量,并赋值, a:=0 同等于 var a int;a=0
b := 5.0 c := int(b) print(c)
<a name="430ce446"></a>
### 8、常量
-
常量使用关键字 const 定义
-
常量还可以用作枚举:
const ( Unknown = 0 Female = 1 Male = 2 )
-
iota 可以被用作枚举值 ???
- 每当 iota 在新的一行被使用时,它的值都会自动加 1
- 每遇到一次 const 关键字,iota 就重置为 0
<a name="89d11830"></a>
### 9、变量
-
声明变量的一般形式是使用 var 关键字: var identifier type
var a int var b bool var str string
或 var ( a int b bool str string )
-
:= 赋值操作符
- 这是使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。
- 使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明。
<a name="0a152d12"></a>
### 10、值类型和引用类型
<a name="896b605a"></a>
### 11、init 函数
初始化总是以单线程执行,并且按照包的依赖关系顺序执行
func init() { print(“123”) }
func main() {
}
<a name="180b309c"></a>
### 12、基本类型和运算符
<a name="cfc209ec"></a>
### 13、指针
-
声明指针
var intP *int
-
使用
intP = &i1 #intP指向i1
<a name="7e604bdf"></a>
## 二、控制结构
<a name="8e8ef79f"></a>
### 2.1、if
if condition1 { // do something } else if condition2 { // do something else }else { // catch-all or default }
<a name="ce76cd51"></a>
### 2.2 switch 结构
switch var1 { case val1: … case val2: … default: … }
<a name="a1f8901f"></a>
### 2.3、for 结构
for i := 1; i <= 15; i++ { }
-
for-range 结构
for pos, char := range str { … }
<a name="d1b54ccf"></a>
## 三、函数
<a name="cdb4cbea"></a>
### 3.1 、类型
- 普通的带有名字的函数
- 匿名函数或者lambda函数(参考 第 6.8 节)
- 方法(Methods,参考 第 10.6 节)
<a name="b1d6405d"></a>
## 四、面向对象
<a name="439a9dd5"></a>
### 4.1、定义实体
type Rectangle struct { width float64 height float64 }
<a name="da1e1c6d"></a>
### 4.2 、实体方法
func (r ReceiverType) funcName(parameters) (results)
(r ReceiverType) : 方法所属的struct
func (r Rectangle) area() float64 { return r.width * r.height }
<a name="ed410af5"></a>
### 4.3、method 继承
package main
import “fmt”
//定义一个Human struct type Human struct { name string age int phone string }
//定义Student 继承Human的全部属性 type Student struct { Human // 匿名字段 school string }
//定义Employee 继承Human的全部属性 type Employee struct { Human // 匿名字段 company string }
// 在 human 上面定义了一个 method func (h *Human) SayHi() { fmt.Printf(“Hi, I am %s you can call me on %s\n”, h.name, h.phone) }
func main() { mark := Student{Human{“Mark”, 25, “222-222-YYYY”}, “MIT”} sam := Employee{Human{“Sam”, 45, “111-888-XXXX”}, “Golang Inc”}
//继承了Human方法
mark.SayHi()
sam.SayHi()
}
<a name="5d18d9cd"></a>
### 4.4、method 重写
//重写SayHi方法 // Employee 的 method 重写 Human 的 method func (e *Employee) SayHi() { fmt.Printf(“Hi, I am %s, I work at %s. Call me on %s\n”, e.name, e.company, e.phone) //Yes you can split into 2 lines here. }
<a name="9faccea7"></a>
## 五、interface
<a name="8e2f6f9d"></a>
### 5.1 interface 定义
// 定义 interface type Men interface { SayHi() Sing(lyrics string) Guzzle(beerStein string) }
<a name="9cf728cd"></a>
### 5.2 interface 实现
package main
type Student2 struct { name string } //实现eat方法 func (s Student2) eat() { println(“吃饭”) } //实现study方法 func (s Student2) study() { println(“学习”) } //技能 type Person interface { //吃饭 eat() //学习 study() }
func main() { p := Student2{name: “Go”}
//Student2实现了Person全部的方法
var m Person
m=p
m.eat()
}
<a name="7dcc93f0"></a>
## 六、反射(reflect)
t := reflect.TypeOf(i) // 得到类型的元数据,通过t我们能获取类型定义里面的所有元素 v := reflect.ValueOf(i) // 得到实际的值,通过 v 我们获取存储在里面的值,还可以去改变值
name := t.Elem().Field(0).Name // 获取定义在 struct 里面第一个字段的字段名 value := v.Elem().Field(0).String() // 获取存储在第一个字段里面的值 //例子 var x float64 = 3.4 v := reflect.ValueOf(x) fmt.Println(“type:”, v.Type()) fmt.Println(“kind is float64:”, v.Kind() == reflect.Float64) fmt.Println(“value:”, v.Float())
//修改值 var x float64 = 3.4 p := reflect.ValueOf(&x) v := p.Elem() v.SetFloat(7.1) ```