一、基本结构和基本数据类型

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 个预定义标识符
    golang语法学习 - 图1

2、包的概念、导入与可见性

  • package main 表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。

  • 一个 Go 程序是通过 import 关键字将一组包链接在一起。 ``` import “fmt” import “os”

或者

import ( “fmt” “os” )

  1. -
  2. 可见性规则
  3. - 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头的标识符的对象就可以被外部包的代码所使用(像面向对象语言中的 public)
  4. - 标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )
  5. -
  6. 使用包的别名来解决包名之间的名称冲突

import fm “fmt”

  1. <a name="e34d9b42"></a>
  2. ### 3、函数
  3. -
  4. 函数规范

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)

  1. <a name="f457ab45"></a>
  2. ### 4、注释

// 开头的单行注释 /**/多行注释

  1. <a name="a972cfba"></a>
  2. ### 5、类型
  3. - 基本类型,如:int、float、bool、string;
  4. - 结构化的(复合的),如:struct、array、slice、map、channel;
  5. - 只描述类型的行为的,如:interface
  6. <a name="a4c4d2f5"></a>
  7. ### 6、Go 程序的一般结构
  8. - Go 程序的执行(程序启动)顺序如下:
  9. - 按顺序导入所有被 main 包引用的其它包,然后在每个包中执行如下流程:
  10. - 如果该包又导入了其它的包,则从第一步开始递归执行,但是每个包只会被导入一次。
  11. - 然后以相反的顺序在每个包中初始化常量和变量,如果该包含有 init 函数的话,则调用该函数。
  12. - 在完成这一切之后,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 //… }

  1. <a name="52629000"></a>
  2. ### 7、类型转换

valueOfTypeB = typeB(valueOfTypeA)

:= 声明变量,并赋值, a:=0 同等于 var a int;a=0

b := 5.0 c := int(b) print(c)

  1. <a name="430ce446"></a>
  2. ### 8、常量
  3. -
  4. 常量使用关键字 const 定义
  5. -
  6. 常量还可以用作枚举:

const ( Unknown = 0 Female = 1 Male = 2 )

  1. -
  2. iota 可以被用作枚举值 ???
  3. - 每当 iota 在新的一行被使用时,它的值都会自动加 1
  4. - 每遇到一次 const 关键字,iota 就重置为 0
  5. <a name="89d11830"></a>
  6. ### 9、变量
  7. -
  8. 声明变量的一般形式是使用 var 关键字: var identifier type

var a int var b bool var str string

或 var ( a int b bool str string )

  1. -
  2. := 赋值操作符
  3. - 这是使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。
  4. - 使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明。
  5. <a name="0a152d12"></a>
  6. ### 10、值类型和引用类型
  7. <a name="896b605a"></a>
  8. ### 11、init 函数

初始化总是以单线程执行,并且按照包的依赖关系顺序执行

func init() { print(“123”) }

func main() {

}

  1. <a name="180b309c"></a>
  2. ### 12、基本类型和运算符
  3. <a name="cfc209ec"></a>
  4. ### 13、指针
  5. -
  6. 声明指针

var intP *int

  1. -
  2. 使用

intP = &i1 #intP指向i1

  1. <a name="7e604bdf"></a>
  2. ## 二、控制结构
  3. <a name="8e8ef79f"></a>
  4. ### 2.1、if

if condition1 { // do something } else if condition2 { // do something else }else { // catch-all or default }

  1. <a name="ce76cd51"></a>
  2. ### 2.2 switch 结构

switch var1 { case val1: … case val2: … default: … }

  1. <a name="a1f8901f"></a>
  2. ### 2.3、for 结构

for i := 1; i <= 15; i++ { }

  1. -
  2. for-range 结构

for pos, char := range str { … }

  1. <a name="d1b54ccf"></a>
  2. ## 三、函数
  3. <a name="cdb4cbea"></a>
  4. ### 3.1 、类型
  5. - 普通的带有名字的函数
  6. - 匿名函数或者lambda函数(参考 第 6.8 节)
  7. - 方法(Methods,参考 第 10.6 节)
  8. <a name="b1d6405d"></a>
  9. ## 四、面向对象
  10. <a name="439a9dd5"></a>
  11. ### 4.1、定义实体

type Rectangle struct { width float64 height float64 }

  1. <a name="da1e1c6d"></a>
  2. ### 4.2 、实体方法

func (r ReceiverType) funcName(parameters) (results)

(r ReceiverType) : 方法所属的struct

func (r Rectangle) area() float64 { return r.width * r.height }

  1. <a name="ed410af5"></a>
  2. ### 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”}

  1. //继承了Human方法
  2. mark.SayHi()
  3. sam.SayHi()

}

  1. <a name="5d18d9cd"></a>
  2. ### 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. }

  1. <a name="9faccea7"></a>
  2. ## 五、interface
  3. <a name="8e2f6f9d"></a>
  4. ### 5.1 interface 定义

// 定义 interface type Men interface { SayHi() Sing(lyrics string) Guzzle(beerStein string) }

  1. <a name="9cf728cd"></a>
  2. ### 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”}

  1. //Student2实现了Person全部的方法
  2. var m Person
  3. m=p
  4. m.eat()

}

  1. <a name="7dcc93f0"></a>
  2. ## 六、反射(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) ```