Go lang Learn Note

标签(空格分隔): Go


Go安装和Go目录

设置环境变量GOROOTGOPATH,前者是go的安装目录,后者是开发工作目录。go get包只会将包下载到第一个工作目录(多个GOPATH的时候)。

Go语言命令行工具介绍

  • go build 用于编译源码文件、代码包、李赖堡
  • go run 可以编译并运行go源码文件
  • go get 主要是用来动态获取远程代码包

GoLand编辑器选择和配置

GoLand下载

一、GO语言基础语法

1. 关键字、标识符

  • GO中保留的关键字(25个)
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
  • GO中预定的标识符,包括基础数据类型和系统内嵌函数(36个)
append bool byte cap close complex
complex64 complex128 uint16 copy false float32
float64 imag int int8 int16 uint32
int32 int64 iota len make new
nil panic uint64 print printIn real
recover string TRUE uint uint8 uintprt

2. 注释

  • // 单行注释
  • /* 多行注释 */

3. 基础结构

// 程序所属包
package main
// 导入依赖包
import "fmt"
// 常量定义
const NAME string = "John"
// 全局变量声明与赋值
var name string = "Bob"
// 一般类型声明
type typeInt int
// 结构声明
type Learn struct { }
// 接口声明
type ILeran interface { }
// 函数定义
func learnFoo() {
fmt.Println("learn foo")
} // main()函数
func main() {
fmt.Println("simple demo")
fmt.Println(NAME)
fmt.Println(name) learnFoo()
}

运行结果

simple demo
John
Bob
learn foo Process finished with exit code 0

4. Package用法

  • package是最基本的分发单位工程管理中依赖关系的体现
  • 每个GO语言源代码文件开头都拥有一个package声明,表示源码文件所属代码包。
  • 要生成GO语言可执行程序,必须要有main的package包,且必须在该包下有main()函数。
  • 同一个路径下只能存在一个package,一个package可以拆分成多个源文件组成。
  • 建议package名称和目录名称一致
  • 同一路径下只能有同一个package名

5.1 import用法

  • 可以导入源代码文件所依赖的package包。
  • 不得导入源代码文件中没有用到的package,否则会编译错误。
  • 两种格式:
import "package1"
import "package2"
...
import (
"package1"
"package2"
...
)

导入未使用包,会抛出如下错误:

import-demo\import-demo.go:5:2: imported and not used: "time"

Compilation finished with exit code 2
  • 如果一个main导入其它包,包将被顺序导入。
  • 如果导入的包中依赖其它包(包B),会首先导入包B,然后初始化包B中的常量和变量,最后如果包B中有init,会自动执行init(),然后回到main中。
  • 所有包导入完成后才会对main中常量和变量进行初始化,然后执行main中的init函数,最后执行main函数。
  • 如果一个包被导入多次,则该包只会被导入一次。

import-demo.go

package main

import (
"fmt"
"./src/show"
"./src/learn"
) // 所有依赖包初始化完成后
// 才执行main的初始化函数
func init() {
fmt.Println("import-demo init")
} func main() {
// learn的init函数只执行了一次
// 可知多次导入只被导入一次
learn.Learn()
show.Show()
fmt.Println("Hello world")
}

show/show.go

package show

import (
"fmt"
"../learn"
) func init() {
fmt.Println("show init")
} func Show() {
learn.Learn()
fmt.Println("show func")
}

learn/learn.go

package learn

import "fmt"

func init() {
fmt.Println("learn init")
} func Learn() {
fmt.Println("learn func")
}

然后我们运行import-demo.go,可见执行结果:

learn init
show init
import-demo init
learn func
learn func
show func
Hello world Process finished with exit code 0

5.2 import别名

  • 将导入的包命名为另一个容易记忆的别名。
  • 点(.)标识的包导入后,调用改包中的函数时可以省略前缀包名。
  • 下划线(_)表示导入该包,但不导入整个包,而是执行该包中的init函数,因此无法通过包名来调用包中的其它函数。使用下划线操作往往是为了注册包里的引擎,让外部可以方便的使用。

别名

import (
myFmt "fmt"
)

6 数据类型

数据类型的出现主要是为了把数据分成所需内存大小不同的数据,可以充分利用内存。

布尔型只可以是true或者false。

字符串类型编码统一为UTF-8。

6.1 整型
类型 描述
uint8 无符号 8 位整型 (0 到 255)
uint16 无符号 16 位整型 (0 到 65535)
uint32 无符号 32 位整型 (0 到 4294967295)
uint64 无符号 64 位整型 (0 到 18446744073709551615)
int8 有符号 8 位整型 (-128 到 127)
int16 有符号 16 位整型 (-32768 到 32767)
int32 有符号 32 位整型 (-2147483648 到 2147483647)
int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
6.2 浮点型
类型 描述
float32 IEEE-754 32位浮点型数
float64 IEEE-754 64位浮点型数
complex64 32位实数和虚数
complex128 64位实数和虚数
6.3 其他数字类型
类型 描述
byte 类似 uint8
rune 类似 int32
uint 32或64位
int 与uint一样大小
uintptr 无符号整型 用于存放一个指针
package main

import (
"fmt"
"unsafe"
) func main() {
// var i uint8 = 1 // 1
// var i uint32 = 1 // 4
var i uint = 1 // 8
fmt.Println(unsafe.Sizeof(i)) var j float32 = 1 // 4
fmt.Println(unsafe.Sizeof(j)) var b bool = true
fmt.Println(b) var bt byte = 1 // 1 类似 uint8
fmt.Println(unsafe.Sizeof(bt)) var r rune = 1 // 4 类似 int32
fmt.Println(unsafe.Sizeof(r))
}
6.4 派生类型
6.5 类型零值和类型别名

类型零值不是空值,是被声明后的默认值。值类型默认值为0,布尔型默认值为false,string默认值为空字符串

package main

import (
"fmt"
"reflect"
"unsafe"
) type 别名 int32
func main() {
var i int32
var j float32
var b bool
var d complex64
var s string fmt.Print("int32: ")
fmt.Println(i) // int32: 0
fmt.Print("float32: ")
fmt.Println(j) // float32: 0
fmt.Print("bool: ")
fmt.Println(b) // bool: false
fmt.Print("complex64: ")
fmt.Println(d) // complex64: (0+0i)
fmt.Print("string: ")
fmt.Println(s) // string: var i_b 别名
var i_n int32 fmt.Print("i_b 别名 默认值: ")
fmt.Print(i_b) // 别名: 0
fmt.Print(", i_b 别名 数据类型: ")
fmt.Print(reflect.TypeOf(i_b))
fmt.Print(", i_b 别名 占用大小: ")
fmt.Println(unsafe.Sizeof(i_b))
// Result: i_b 别名 默认值: 0, i_b 别名 数据类型: main.别名, i_b 别名 占用大小: 4 fmt.Print("i_n int32 默认值: ")
fmt.Print(i_n) // 别名: 0
fmt.Print(", i_n int32 数据类型: ")
fmt.Print(reflect.TypeOf(i_n))
fmt.Print(", i_n int32 占用大小: ")
fmt.Println(unsafe.Sizeof(i_n))
// Result: i_n int32 默认值: 0, i_n int32 数据类型: int32, i_n int32 占用大小: 4 // 不同类型不能运算, 包括别名
}
6.6 类型存储大小

7 变量与常量

7.1 变量声明 初始化与赋值
  • 变量声明和赋值

变量声明: var [变量名称] <变量类型>

变量赋值: [变量名称] = [值]

声明与赋值同时进行: var [变量名称] <变量类型> = [值]

分组声明:

var (
i int
j float32
name string = "abc"
)

同一行声明多个变量和赋值: var a, b, c int = 1,2,3或者a, b := 1,2

全局变量的声明必须使用var关键字,局部变量可以省略

特殊变量下划线 _

package main

import (
"fmt"
"reflect"
) // 全局变量var是必须的
var a int
var b string = "abc"
// 分组方式
var (
c string
d int
e string = "小明"
) func main() {
fmt.Println(a) // 0 a = 123 // 赋值
fmt.Println(a) // 123 fmt.Println(b) // abc fmt.Print("c: ")
fmt.Print(c)
fmt.Print(", d: ")
fmt.Print(d)
fmt.Print(", e: ")
fmt.Println(e)
// c: , d: 0, e: 小明 var f, g, h int = 1, 2, 3
fmt.Print("f: ")
fmt.Print(f)
fmt.Print(", g: ")
fmt.Print(g)
fmt.Print(", h: ")
fmt.Println(h)
// f: 1, g: 2, h: 3 var i, j, k = 11, 21.3, 31
fmt.Print("i: ")
fmt.Print(i)
fmt.Print("i 数据类型为: ")
fmt.Print(reflect.TypeOf(i))
fmt.Print(", j: ")
fmt.Print(j)
fmt.Print(", j 数据类型为: ")
fmt.Print(reflect.TypeOf(j))
fmt.Print(", k: ")
fmt.Println(k)
// i: 11i 数据类型为: int, j: 21.3, j 数据类型为: float64, k: 31 // 冒号简写,只能在函数体内使用
l, m, n := 11, 21.3, "c"
fmt.Print("l: ")
fmt.Print(l)
fmt.Print(", m: ")
fmt.Print(m)
fmt.Print(", n: ")
fmt.Println(n)
// l: 11, m: 21.3, n: c // 下划线
var o, _, p = 11, 21.3, 31
fmt.Print("o: ")
fmt.Print(o)
fmt.Print(", p: ")
fmt.Print(p)
// fmt.Print(", _: ")
// fmt.Println(_) // 下划线不能被打印
// o: 11, p: 31
}
7.2 变量类型转换

不能隐式转换,必须显式

类型转换只能发生在两种兼容类型之间

类型转换格式: [变量名称] [:]= <目标类型>([需要转换的变量名称])

package main

import (
"fmt"
"reflect"
) func main() {
var a int = 1
var b float32 = 2.3 c := float32(a) fmt.Print(c)
fmt.Print(" ")
fmt.Println(reflect.TypeOf(c)) d := int32(b)
fmt.Print(d)
fmt.Print(" ")
fmt.Println(reflect.TypeOf(d))
}
7.3 变量可见性规则

大写字母开头的变量是可导出的,是公用变量

小写字母开头的变量是私有变量,不可导出被读取

package B

// 大写字母开头的变量是可导出的,是公用变量
// 小写字母开头的变量是私有变量,不可导出被读取
var a = "变量a" var A = "变量A"
package main

import (
"fmt"
"./B"
) func main() {
fmt.Println(B.A) // 变量A
}
7.4 常量
  • 定义形式 类型范围

显示: const identifier <type> = value

隐式: const identifier = value ,无类型常量

常量可以使用内置表达式定义,len() unsafe.Sizeof()

只支持布尔型、数字型(整数型、浮点型和复数)、字符串型

常量不能使用 := 语法定义。

package main

import "fmt"

const a string = "常量a" // 显式
const b = "常量b" // 隐式
const (
c string = "常量c"
d = "常量d"
)
const e, _, f = "常量e", "下划线", 6
const g = len(a) // 只支持内置函数 func main() {
fmt.Println(a) // 常量a
fmt.Println(b) // 常量b
fmt.Println(c) // 常量c
fmt.Println(d) // 常量d
fmt.Println(e) // 常量e
fmt.Println(f) // 6
fmt.Println(g) // 7
}
  • iota的使用

在const关键字出现时将被重置为0

const中每新增一行常量声明将使iota +1

跳值使用法、插队使用法、表达式隐式使用法、单行使用法

package main

import "fmt"

func main() {
// 在const关键字出现时将被重置为0
const h = iota
const i = iota
fmt.Print("h值为: ")
fmt.Print(h)
fmt.Print(", i值为: ")
fmt.Println(i)
// h值为: 0, i值为: 0 // const中每新增一行常量声明将使iota +1
const (
j = iota
k = iota
)
fmt.Print("j值为: ")
fmt.Print(j)
fmt.Print(", k值为: ")
fmt.Println(k)
// j值为: 0, k值为: 1 // 跳值使用法
const (
l = iota
m = iota
_
n = iota
)
fmt.Print("l值为: ")
fmt.Print(l)
fmt.Print(", m值为: ")
fmt.Print(m)
fmt.Print(", n值为: ")
fmt.Println(n)
// l值为: 0, m值为: 1, n值为: 3 // 插队使用法
const (
o = iota
p = 3.14
q = iota
)
fmt.Print("o值为: ")
fmt.Print(o)
fmt.Print(", p值为: ")
fmt.Print(p)
fmt.Print(", q值为: ")
fmt.Println(q)
// o值为: 0, p值为: 3.14, q值为: 2 // 表达式隐式使用法
// 自动向上使用非空表达式
const (
r = iota * 2
s = iota * 3
t
u
)
fmt.Print("r值为: ")
fmt.Print(r)
fmt.Print(", s值为: ")
fmt.Print(s)
fmt.Print(", t值为: ")
fmt.Print(t)
fmt.Print(", u值为: ")
fmt.Println(u)
// r值为: 0, s值为: 3, t值为: 6, u值为: 9 const (
aa, bb = iota, iota + 3
cc, dd
ee = iota
)
fmt.Print("aa值为: ")
fmt.Print(aa)
fmt.Print(", bb值为: ")
fmt.Print(bb)
fmt.Print(", cc值为: ")
fmt.Print(cc)
fmt.Print(", dd值为: ")
fmt.Print(dd)
fmt.Print(", ee值为: ")
fmt.Println(ee)
// aa值为: 0, bb值为: 3, cc值为: 1, dd值为: 4, ee值为: 2
}

8.运算符

8.1 算数运算符

+, -, *, /, %, ++, --

++, --只能在变量后面用。

8.2 关系运算符

==, !=, >, >=, <, <=

8.3 逻辑运算符

&&, ||, !

8.3 按位运算符
  • & 按位与 两者都为1则结果为1
  • | 按位或 有一个为1 结果为1
  • ^ 按位异或 对应位 不同数值时结果为1,相同数值为0
  • << 左移 把数整体向左移动
  • >> 右移 把数整体向右移动

package main

import "fmt"

func main() {
a := byte(0)
b := byte(1) fmt.Print("a 的值为: ")
fmt.Println(a)
fmt.Print("b 的值为: ")
fmt.Println(b) fmt.Println("") fmt.Print("a&b 的值为: ")
fmt.Println(a&b) fmt.Print("a|b 的值为: ")
fmt.Println(a|b) fmt.Print("a^b 的值为: ")
fmt.Println(a^b)
fmt.Print("a^a 的值为: ")
fmt.Println(a^a) fmt.Print("b << 1 的值为: ")
fmt.Println(b << 1) fmt.Print("b >> 1 的值为: ")
fmt.Println(b >>1 )
}
a 的值为: 0
b 的值为: 1 a&b 的值为: 0
a|b 的值为: 1
a^b 的值为: 1
a^a 的值为: 0
b << 1 的值为: 2
b >> 1 的值为: 0 Process finished with exit code 0
8.4 赋值运算符
  • = 赋值
  • += 加等
  • -= 减等
  • *= 乘等
  • /= 除等
  • %= 余等 a %= 2 相当于 a = a % 2
  • <<= 左移后赋值 a <<= 2 相当于 a = a << 2
  • >>= 右移后赋值 a >>= 2 相当于 a = a >> 2
  • &= 按位与后赋值 a &= 2 相当于 a = a & 2
  • ^= 按位异后赋值 a ^= 2 相当于 a = a ^ 2
  • |= 按位或后赋值 a |= 2 相当于 a = a | 2

9 控制语句

9.1 if else
9.2 switch, select
9.3 for
// for 循环
for i := 1; i <= 10; i++ {
fmt.Println(i)
time.Sleep(1 * time.Second)
} // forEach 循环
b := []string{"字符串1", "字符串2", "字符串3", "字符串4", "字符串5"}
for key, value := range b {
fmt.Print("key的值为: ")
fmt.Println(key)
fmt.Print("value的值为: ")
fmt.Println(value)
}
9.4 goto, break, continue
  • goto 跳转到指定流程
  • break 跳出循环
  • continue 跳出本次循环
// goto
goto One
fmt.Println("代码块1")
fmt.Println("代码块2")
One:
fmt.Println("代码块One")
fmt.Println("代码块Two") // break
for i := 1; i <= 3; i++ {
for j := 0; j < 3; j++ {
fmt.Print("循环体-")
fmt.Print(i)
fmt.Print("-")
fmt.Println(j)
break
}
} // continue
for i := 0; i < 3; i++ {
if i > 1 {
fmt.Println("满足i > 1, continue, 跳出本次循环")
continue
} fmt.Print("当前下标为: ")
fmt.Println(i)
}

Last updated by Jehorn, Aug 16 2018

GO Lang学习笔记 - 基础知识的更多相关文章

  1. jQuery学习笔记 - 基础知识扫盲入门篇

    jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...

  2. three.js学习笔记--基础知识

    基础知识 从去年开始就在计划中的three.js终于开始了 历史介绍 (摘自ijunfan1994的转载,感谢作者) OpenGL大概许多人都有所耳闻,它是最常用的跨平台图形库. WebGL是基于Op ...

  3. SQLServer学习笔记<>.基础知识,一些基本命令,单表查询(null top用法,with ties附加属性,over开窗函数),排名函数

    Sqlserver基础知识 (1)创建数据库 创建数据库有两种方式,手动创建和编写sql脚本创建,在这里我采用脚本的方式创建一个名称为TSQLFundamentals2008的数据库.脚本如下:   ...

  4. Java Script 学习笔记 -- 基础知识

    Java script 概述 java Script 的简介 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为 ...

  5. java虚拟机JVM学习笔记-基础知识

    最近使用开发的过程中出现了一个小问题,顺便记录一下原因和方法--java虚拟机 媒介:JVM是每一位从事Java开发工程师必须翻越的一座大山! JVM(Java Virtual Machine)JRE ...

  6. hadoop学习笔记——基础知识及安装

    1.核心 HDFS  分布式文件系统    主从结构,一个namenoe和多个datanode, 分别对应独立的物理机器 1) NameNode是主服务器,管理文件系统的命名空间和客户端对文件的访问操 ...

  7. php学习笔记——基础知识(2)

    9.PHP语句 if 语句 - 如果指定条件为真,则执行代码 if...else 语句 - 如果条件为 true,则执行代码:如果条件为 false,则执行另一端代码 if...else if.... ...

  8. php学习笔记——基础知识(1)

    1.PHP 脚本在服务器上执行,然后向浏览器发送回纯 HTML 结果. 2.基础 PHP 语法 1)PHP 脚本可放置于文档中的任何位置. 2)PHP 脚本以 <?php 开头,以 ?> ...

  9. Redux学习笔记-基础知识

      Redux概述 是什么:Redux是管理状态的容器,提供可预测的状态管理. 怎么做:Redux主要是用来管理组件或者应用的状态,本质上跟一个事件处理器差不多.通过分发action触发reduce来 ...

随机推荐

  1. 洛谷 P2482 loj #2885 [SDOI2010]猪国杀 题解【模拟】【贪心】【搜索】

    好玩的模拟题. 以后要经常写模拟题鸭 题目描述 游戏背景 <猪国杀>是一种多猪牌类回合制游戏,一共有\(3\)种角色:主猪,忠猪,反猪.每局游戏主猪有且只有\(1\)只,忠猪和反猪可以有多 ...

  2. HDU 6357.Hills And Valleys-动态规划(区间翻转l,r找最长非递减子序列)

    题意:给一串由n个数字组成的字符串,选择其中一个区间进行翻转,要求翻转后该字符串的最长非降子序列长度最长,输出这个最长非降子序列的长度以及翻转的区间的左右端点 #include<bits/std ...

  3. UESTC - 1357 前缀和维护

    有点小细节需要注意 sum实时维护有效的连续和 /*H E A D*/ ll dp1[maxn],dp2[maxn]; ll a[maxn],n,sum; int main(){ while(~iin ...

  4. docker 启动容器报错

    2018-10-24 报错信息: /usr/bin/docker-current: Error response from daemon: driver failed programming exte ...

  5. Hadloop

    Hadoop是分布式文件系统 并行处理系统:高效存储和高效处理组件 Mapreduce,函数式编程机制,分Map阶段和reduce阶段,他不但是一个编程方式,同时也是个运行框架,它分两个阶段 Map阶 ...

  6. SVN创建资源库和远程连接配置

    SVN创建资源库和远程连接配置 本机安装的是TortoiseSVN-1.7.5.22551-win32-svn-1.7.3.msi 安装好后会在鼠标右键中出现如图最后两项的选项: 创建svn资源库: ...

  7. 迪米特法則 Law of Demeter

    又稱為"最小知識"原則, 若對Law of Demeter做一個簡單總結: 任何對象的任何方法只能調用以下對象中的方法: (1) 該對象本身 (2) 所傳入的參數對象 (3) 它所 ...

  8. Kubernetes系列:(1) 初探

    1. 背景 在部门内容组织了一次K8s的培训,普及了下K8s的概念.框架.操作等,为便于后期查阅,也为了进一步深究K8s,因此开展K8s系列,周期不定- 2. 概念 (1) 含义:来自希腊语,意为&q ...

  9. Java学习第二十天

    1:递归(理解) (1)方法定义中调用方法本身的现象 举例:老和尚给小和尚讲故事,我们学编程 (2)递归的注意事项: A:要有出口,否则就是死递归 B:次数不能过多,否则内存溢出 C:构造方法不能递归 ...

  10. PLC通信网络

    PLC通信网络的分层 PLC通信网络大致可分为3层,管理层,单元层以及现场执行(AS-I)层.如下图所示. 在PLC通信网络的三层架构中,管理层,通信方式包括MPI,工业以太网(Profinet)以及 ...