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. UVALive - 6952 DP 分段/隔板

    题意:商品总价按四舍五入计算,n个物品最多可分\(d+1\)段,求最小代价 \(dp[i][j]\):\(j\)个物品分\(i\)段 注意一个技巧是只在需要分出新的段时才四舍五入(旧段结算),这样就避 ...

  2. 关于webpack 以及 webpack配置和常用插件的学习记录 (1)

    主要概念: Entry :   webpack的入口,构建的第一步从entry开始. Output :   输出,经过webpack处理后的得到最终想要的代码. Loader :   模块转换工具,把 ...

  3. Unix或Linux中&、jobs、fg、bg等命令的使用方法

    [From] http://blog.sina.com.cn/nenutechnology fg.bg.jobs.&.ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令 ...

  4. How to download Heavy Duty Diagnostic Caterpillar SIS 2018 software

    Maybe you find there are supplied Caterpillar SIS 2018 software free download in search engine, that ...

  5. vuex中filter的使用 && 快速判断一个数是否在一个数组中

    vue中filter的使用 computed: mapState({ items: state => state.items.filter(function (value, index, arr ...

  6. nodejs日志管理log4js

    常用的2种配置: 1.按文件大小分片,备份若干数量的文件 var log4js = require('log4js'); log4js.configure({ "appenders" ...

  7. javascript遍历表

    定义表结构 1. 通过id遍历 <html> <body> <table id="tb" border="1"> <t ...

  8. 【Linux相识相知】文本处理工具之grep\egrep\fgrep及正则表达式

    常说Linux上有文本处理的三剑客,grep.sed和awk,本文就grep做出详细的描述,并引出正则表达式. grep NAME:打印模式匹配的行 SYNOPISIS: grep [OPTIONS] ...

  9. [转]Asp.net Core 使用Redis存储Session

    本文转自:http://www.cnblogs.com/hantianwei/p/5723959.html 前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储 ...

  10. Javascript “等于”

    JavaScript支持“=”.“==”和“===”运算符. 我们应当理解这些(赋值.相等.恒等)运算符之间的区别,并在编码过程中小心使用. == equality 等同,用于一般比较,在比较的时候可 ...