1.go的语言结构

基础组成部分有:包声明、引入包、函数、变量、语句&表达式、注释
eg.

package main
import "fmt"
func main() {
//一个简单程序
   fmt.Println("Hello, World!")
}

2.go中的标识符

标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(AZ和az)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字
*以下是有效的标识符:
mahesh kumar abc move_name a_123
myname50 _temp j a23b9 retVal
*以下是无效的标识符:
1ab(以数字开头)
case(Go 语言的关键字)
a+b(运算符是不允许的)

2.1 go中标识符大小写的区分
当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);
标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )

3.go中各标识符的声明

// 当前程序的包名
package main
// 导入其他包
import . "fmt"
// 常量定义
const PI = 3.14         //常量标识符   常量名  =   值
// 全局变量的声明和赋值
var name = "gopher"     //变量标识符   变量名  =   值

// 一般类型声明
type newType int
// 结构的声明
type gopher struct{}
// 接口的声明
type golang interface{}
// 由main函数作为程序入口点启动
func main() {   
 Println("Hello World!")
 }

4.golang的数据类型

在 Go 编程语言中,数据类型用于声明函数和变量,数据类型的出现是为了把数据分成所需内存大小不同的数据,大数据分配大内存,小数据分配小内存
1 布尔类型 true false 例:var a bool = true
2 数组类型
2.1整型 int
1)uint8 无符号 8 位整型 (0 到 255)
2)uint16 无符号 16 位整型 (0 到 65535)
3)uint32 无符号 32 位整型 (0 到 4294967295)
4)uint64 无符号 64 位整型 (0 到 18446744073709551615)
5)int8 有符号 8 位整型 (-128 到 127)
6)int16 有符号 16 位整型 (-32768 到 32767)
7)int32 有符号 32 位整型 (-2147483648 到 2147483647)
8)int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
2.2浮点型 float
1)float32 32位浮点型数
2)float64 64位浮点型数
3)complex64 32位实数和虚数
4)complex128 64位实数和虚数

2.3其他数字类型
1)byte 类似 uint8
2)rune 类似 int32
3)uint 32 或 64 位
4)int 与 uint 一样大小
5)uintptr 无符号整型,用于存放一个指针

3.字符串类型
字符串就是一串固定长度的字符连接起来的字符序列,使用 + 连接

4.派生类型
● (a) 指针类型(Pointer)● (b) 数组类型● © 结构化类型(struct)● (e) 函数类型● (f) 切片类型(slice)● (g) 接口类型(interface)● (h) Map 类型(集合)

5.go中数值类型的声明方式

全局变量声明(有类型的声明),忽略类型的声明(系统自动识别数值类型),简短声明( := ),一般声明(形式与第一种相同),赋值操作

//示例代码
var isActive bool  // 全局变量声明
var enabled, disabled = true, false  // 忽略类型的声明
func test() {    valid := false      // 简短声明(使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明)   
 var available bool  // 一般声明   
  available = true    // 赋值操作}

6.golang变量

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字,声明变量的一般形式是使用 var 关键字

var xxxname(变量名) type
//可以一次声明多个变量:
var iden1, iden2 type

7.golang常量

常量是指在程序运行时,不会被修改的量,它是一个简单值的标识符。常量中的数据类型只能是布尔型、数字型(整数型、浮点型和复数)和字符串型
1. 常量的定义格式 const 名字 type = value
可以省略类型说明符 type ,因为编译器可以根据变量的值来推断其类型。
*显式类型定义: const b string = “abc”
*隐式类型定义: const b = “abc”
多个相同类型的声明可以简写为: const c_name1, c_name2 = value1, value2
多重赋值 const a, b, c = 1, false, “str”

  1. 在定义常量组时,如果不提供初始值,则表示将使用上行的表达式,使用上行已经初始化的表达式的值
package mainimport "fmt"const (    a = 1    b    c    d)
func main() {  
  fmt.Println(a)    // b、c、d没有初始化,使用上一行(即a)的值 
  fmt.Println(b)   // 输出1    
  fmt.Println(c)   // 输出1   
  fmt.Println(d)   // 输出1
  }

3.iota:特殊常量,可以认为是一个可以被编译器修改的常量

  iota 只是在同一个 const 常量组内递增,每当有新的 const 关键字时,iota 计数会重新开始
package main
const (    i = iota    j = iota    x = iota)
const xx = iota    //新的const关键字出现,iota重新从0开始
const yy = iota    //新的const关键字出现,iota重新从0开始
func main(){ 
   println(i, j, x, xx, yy)
   }
   // 输出是 0 1 2 0 0

8.golang运算符

 运算符用于在程序运行时执行数学或逻辑运算,Go 语言内置的运算符有:

算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符
1.算术运算符

  • 相加 +     相减   -   相乘 *    相除  / 
    
  •  自加 ++        自减   --       求余  %             
    

2.关系运算符
== 检查两个值是否相等
!= 检查两个值是否不相等
> 检查左边值是否大于右边值
< 检查左边值是否大于右边值
>= 检查左边值是否大于等于右边值
<= 检查左边值是否小于等于右边值

3.逻辑运算符(返回值为布尔值)
&& 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False
|| 逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False
! 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True

4.位运算符(位运算符对整数在内存中的二进制位进行操作,即整数转换为二进制再操作)
& 按位与,双目运算符(要求两个数值参加运算),参与运算的两数各对应的二进位相与(相乘)
| 按位或,参与运算的两数各对应的二进位相或(相加)
^ 按位异或,运算的两数不同时为true,相同时为false
<< 左移运算符,左移n位就是乘以2的n次方
>> 右移运算符,右移n位就是除以2的n次方

5.赋值运算符
= 简单的赋值运算符,将一个表达式的值赋给一个左边的值
+= 相加后再赋值
-= 相减后再赋值
*= 相乘后再赋值
/= 相除后再赋值
<<= 左移后赋值
>>= 右移后赋值
&= 按位与后赋值
^= 按位异或后赋值
|= 按位或后赋值
%= 求余后再赋值

6.其他运算符

& 返回变量存储地址
&a; 将给出变量的实际地址
* 指针变量
*a; 是一个指针变量
*指针变量 * 和地址值 & 的区别:指针变量保存的是一个地址值,会分配独立的内存来存储一个整型数字。 当变量前面是 * 标识时,且赋给的新变量输出时也是 * 标识时,指向的才是地址中存放的变量值; 变量前面是 & 标识,且赋给的新变量输出时没有 * 或 &标识,指向的是地址值
eg.

func main() {   
var a int = 4  
 var ptr *int  
  ptr = &a   println("a的值为", a)    // 4 
    println("*ptr为", *ptr)  // 4  
     println("ptr为", ptr)    // 824633794744
     }

9.golang条件语句

条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为 true 来决定是否执行指定语句,并在条件为 false 的情况在执行另外的语句。Go 语言提供了以下几种条件判断语句:
if 语句 : if 语句 由一个布尔表达式后紧跟一个或多个语句组成
if…else 语句 : if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行 if 布尔表达式 { /* 在布尔表达式为 true 时执行 / } else { / 在布尔表达式为 false 时执行 */ }
Go 的 if 还有一个强大的地方就是条件判断语句里面允许声明一个变量,这个变量的作用域只能在该条件逻辑块内,其他地方不起作用,
if 还有另外一种形式,它包含一个 statement 可选语句部分,该组件在条件判断之前运行

if嵌套语句 :可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句
if 布尔表达式 1 {
/* 在布尔表达式 1 为 true 时执行 /
if 布尔表达式 2 {
/
在布尔表达式 2 为 true 时执行 */
}
}

switch 语句: 用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止, case 最后自带 break 语句,匹配成功后就不会执行其他 case,如果需要执行后面的 case,可以使用 fallthrough强制执行,也可以使用break 。同时测试多个可能符合条件的值,使用逗号分割,

 使用 fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true

10.golang循环语句

  1. for循环(for 循环是一个循环控制结构,可以执行指定次数的循环)

for语句执行过程如下:
1、先对表达式 1 赋初值;
2、判别赋值表达式 init 是否满足给定条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句
2.嵌套循环 (在循环内使用循环)

3.循环控制语句(循环控制语句可以控制循环体内语句的执行过程)
GO 语言支持以下几种循环控制语句:
3.1 break语句
3.2 continue语句
跳过当前循环的剩余语句,然后继续进行下一轮循环
3.3 goto语句
将控制转移到被标记的语句,通常与条件语句配合使用,用来实现条件转移, 构成循环,跳出循环体等功能。但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难
3.4 无限循环
如果循环中条件语句永远不为 false 则会进行无限循环,可以通过 for 循环语句中只设置一个条件表达式来执行无限循环

11.函数

1.函数定义
函数是基本的代码块,用于执行一个任务,Go 语言最少有个 main() 函数。可以通过函数来划分不同功能,执行指定的任务
函数格式如下:
func 函数名 (参数列表 参数类型) 返回值{
函数体
}
参数列表指定的是参数类型、顺序、及参数个数,参数是可选的,函数也可以不包含参数

2.函数调用
当创建函数时,定义了函数的功能,则通过调用该函数来执行指定任务,调用函数,向函数传递参数,并返回值
eg.

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 
}

以上实例在 main() 函数中调用 max()函数,执行结果为:最大值是 : 200

3.函数返回多个值
函数可以返回多个值,如下

package main
import "fmt"

//定义一个返回值为两个字符串的函数
func swap(x, y string) (string, string) {
   return y, x
}

func main() {
    //main函数中调用swap函数,并对将返回的两个字符串赋给a,b  a,b通过简洁声明进行初始化
   a, b := swap("Google", "Runoob")
   fmt.Println(a, b)
}
以上实例执行结果为:
Runoob Google
  1. 函数的用法
    1)函数作为另一个函数的实参,函数定义后可作为另外一个函数的实参数传入
    2)闭包 (匿名函数,在动态编程中使用)
    3)方法(方法就是包含了一个接受者的函数)

12. 变量的作用域

作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。
Go 语言中变量可以在三个地方声明:
函数内定义的变量称为局部变量
函数外定义的变量称为全局变量
函数定义中的变量称为形式参数,会作为函数的局部变量来使用
局部变量:在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量
全局变量:在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用,全局变量可以在任何函数中使用
Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑

13. 数组

13.1. 数组的含义:数组是具有相同类型、已编号的数据项序列,数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始
13.2. 声明数组: 数组声明需要指定元素类型及元素个数,
语法格式为:var 数组名[大小] 数组类型
13.3. 初始化数组: 即给数组赋值
13.4. 访问数组元素:通过索引来取值

14.指针

1.指针的含义 一个指针变量指向了一个值的内存地址

2.声明指针 类似于变量和常量,在使用指针前需要声明指针。指针声明格式如下: var 指针的变量名 *指针类型 * 号用于指定变量是作为一个指针

  1. 如何使用指针
    定义指针变量。
    为指针变量赋值。
    访问指针变量中指向地址的值。
    在指针变量前面加上 * 号(前缀)来获取指针所指向的内容

  2. 空指针 当一个指针被定义后没有分配到任何变量时,它的值为 nil。nil 指针也称为空指针。nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。一个指针变量通常缩写为 ptr

5.指向指针的指针变量(**) 一个指针变量存放的是另一个指针变量的地址

15. 结构体

  1. 结构体的概念 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合,可以为不同项定义不同的数据类型,结构体表示一项记录

  2. 结构体的定义
    结构体定义需要使用 type 和 struct 语句。type 语句设定了结构体的名称;struct 语句定义一个新的数据类型, struct 关键字也可以定义结构体类型变量,结构体中有一个或多个成员
    type 结构体名字 struct{
    成员定义
    成员定义
    }
    一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:
    变量名 := 结构体名 {value1, value2…valuen}

    变量名 := 结构体名 { key1: value1, key2: value2…, keyn: valuen}

3.访问结构体成员
如果要访问结构体成员,需要使用点号 . 操作符,格式为:结构体.成员名

4.结构体作为函数参数 结构体类型也可以作为参数传递给函数

15.结构体指针

可以像定义其他指针变量一样定义结构体的指针变量,用来存储结构体变量的地址
格式:
var 结构体指针名 *结构体  
将 & 符号放置于结构体变量前,查看结构体变量地址: 
      结构体指针名 = &结构体    使用结构体指针访问结构体成员
      ,使用 "." 操作符:        struct_pointer.title

16.切片 (golang中切片是对数组的抽象,切片长度不固定)

Go 数组的长度不可改变,与数组相比切片的长度是不固定的,可以追加元素。切片由三部分组成:指向底层数组的指针、len、cap

  1. 切片的定义
    ① 声明一个未指定大小的数组来定义切片,切片不需要说明长度:
    var 数组名[]type
    ② 使用make()函数来创建切片: var slice1 []type = make([]type, len)

    也可以简写为 slice1 := make([]type, len)
    也可以指定容量,其中capacity为可选参数
    make([]type, length, capacity)
    这里 len 是数组的长度并且也是切片的初始长度,cap代表容量

  2. 切片初始化
    1)直接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是1,2,3.其cap=len=3(容量=长度) ----> s :=[] int {1,2,3}
    2)初始化切片s为数组arr的引用 ----> s := arr[:]
    3)将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片 ----> s := arr[startIndex:endIndex]

  1. 默认 startIndex 时将表示从arr的第一个元素开始 -----> s := arr[:endIndex]
  2. 默认 endIndex 时将表示一直到arr的最后一个元素 ----> s := arr[startIndex:]
  3. 通过切片s初始化切片s1 ----> s1 := s[startIndex:endIndex]
  4. 通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片 ----> s :=make([]int,len,cap)
  1. len()和cap()函数
    len() 方法 ----> 获取长度 cap() 方法 -----> 测量切片最大容量

  2. append()和copy()函数
    append() 方法 ----> 向切片追加新元素

copy() 方法 -----> 拷贝切片A的内容到切片B

  5. 空(nil)指针

一个切片在未初始化之前默认为 nil,长度为 0

 6. 切片截取

可以通过设置下限(包含,默认下限为0)及上限(不包含,默认上限为len)来设置截取切片 [lower-bound:upper-bound]

17.范围(Range)

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对

18.Map(集合)

Map 是一种无序的键值对的集合(使用hash表来实现无序),Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值
Map的定义:使用内建函数 make 或者用 map 关键字来定义 Map

  1. 递归函数 (递归,就是在运行的过程中调用自己,在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中)

14.类型转换 (将一种数据类型的变量转换为另外一种类型的变量)
类型转换基本格式: 转换后的类型(表达式)

  1. 接口(interface)接口是Go 语言提供的另一种数据类型,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口

更多推荐

菜鸟教程------Golang学习笔记