标准命令
Go语言中包含了大量用于处理Go语言代码的命令和工具。其中,go命令就是最常用的一个,它有许多子命令。这些子命令都拥有不同的功能,如下所示。
build:用于编译给定的代码包或Go语言源码文件及其依赖包。
clean:用于清除执行其他go命令后遗留的目录和文件。
doc:用于执行godoc命令以打印指定代码包。
env:用于打印Go语言环境信息
fix:用于执行go tool fix命令以修正给定代码包的源码文件中包含的过时语法和代码调用
fmt:用于执行gofmt命令以格式化给定代码包中的源码文件
get:用于下载和安装给定代码包及其依赖包(提前安装git或hg)
list:用于显示给定代码包的信息
run:用于编译并运行给定的命令源码文件
install:编译包文件并编译整个程序
test:用于测试给定的代码包
tool:用于运行Go语言的特殊工具
version:用于显示当前安装的Go语言的版本信息
常用命令 build命令和run命令
两个命令的区别,build命令只会编译代码同时生成一个可执行程序,需要再次手动执行该可执行程序,run命令是编译并直接运行程序,并不会生成可执行程序
go build xxx.go //编译go代码,生成一个可执行程序
xxx.exe //然后,运行可执行程序 xxx
go run xxx.go //不生成程序,直接运行
其他知识点
cls命令: windows cmd清屏命令
启动go程序
go源码当中必须要包含一个main package,并且在该package中包含一个main函数(该函数是Go可执行程序的执行起点)
同一工作目录下,只能其中一个go文件可存在main函数
//1) go语言以包作为管理单位
//2) 每个文件必须先声明包
//3) 程序必须有一个main包(重要)
package main
import "fmt"
//入口函数
func main() { //左括号必须和函数名同行
//打印
//"hello go"打印到屏幕, Println()会自动换行
//调用函数,大部分都需要导入包
/*
这也是注释, 这是块注释
*/
fmt.Println("hello go") //go语言语句结尾是没有分号
fmt.Println("hello itcast")
}
Go语言的main()函数不能带参数,也不能定义返回值。
在包声明之后,是一系列的import语句,用于导入该程序所依赖的包。由于本示例程序用到了Println()函数,所以需要导入该函数所属的fmt包。
所有Go函数以关键字func开头。一个常规的函数定义包含以下部分:
func 函数名(参数列表)(返回值列表) {
// 函数体
}
注意:强制左花括号{的放置位置,如果把左花括号{另起一行放置,这样做的结果是Go编译器报告编译错误。
Go程序的代码注释与C++保持一致,即同时支持以下两种用法:
/* 块注释 */
// 行注释
命名
Go语言中的函数名、变量名、常量名、类型名、语句标号和包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线。大写字母和小写字母是不同的:heapSort和Heapsort是两个不同的名字。
Go语言中类似if和switch的关键字有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
此外,还有大约30多个预定义的名字,比如int和true等,主要对应内建的常量、类型和函数。
内建常量:
true false iota nil
内建类型:
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
内建函数:
make len cap new append copy close delete
complex real imag
panic recover
变量
(1)变量声明
Go语言引入了关键字var,而类型信息放在变量名之后,示例如下:
var v1 int
var v2 int
//一次定义多个变量
var v3, v4 int
var (
v5 int
v6 int
)
(2)变量初始化
var v1 int = 10 // 方式1
var v2 = 10 // 方式2,编译器自动推导出v2的类型
v3 := 10 // 方式3,编译器自动推导出v3的类型
fmt.Println("v3 type is ", reflect.TypeOf(v3)) //v3 type is int
//出现在 := 左侧的变量不应该是已经被声明过,:=定义时必须初始化
var v4 int
v4 := 2 //err
(3)变量赋值
var v1 int
v1 = 123
var v2, v3, v4 int
v2, v3, v4 = 1, 2, 3 //多重赋值
i := 10
j := 20
i, j = j, i //多重赋值
(4)匿名变量
_(下划线)是个特殊的变量名,任何赋予它的值都会被丢弃:
_, i, _, j := 1, 2, 3, 4
func test() (int, string) {
return 250, "sb"
}
_, str := test()
(5)变量的使用
package main //必须有一个main包
import "fmt" //导入包含,必须要使用
func main() {
//变量,程序运行期间,可以改变的量
//1、声明格式 var 变量名 类型, 变量声明了,必须要使用
//2、只是声明没有初始化的变量,默认值为0
//3、同一个{}里,声明的变量名是唯一的
var a int
fmt.Println("a = ", a)
//4、可以同时声明多个变量
//var b, c int
a = 10 //变量的赋值
fmt.Println("a = ", a)
//2、变量的初始化,声明变量时,同时赋值
var b int = 10 //初始化,声明变量时,同时赋值(一步到位)
b = 20 //赋值, 先声明,后赋值
fmt.Println("b = ", b)
//3、自动推导类型,必须初始化,通过初始化的值确定类型(常用)
c := 30
//%T打印变量所属的类型
fmt.Printf("c type is %T\n", c)
}
(6)自动推导类型
package main //必须有一个main包
import "fmt"
func main() {
//赋值,赋值前,必须先声明变量
var a int
a = 10 //赋值,可以使用n次
a = 20
a = 30
fmt.Println("a = ", a)
//:=, 自动推导类型,先声明变量b,再给b赋值为20
//自动推导,同一个变量名只能使用一次,用于初始化那次
b := 20
fmt.Println("b = ", b)
//b := 30 //前面已经有变量b,不能再新建一个变量b
b = 30 //只是赋值,可以的
fmt.Println("b2 = ", b)
}
(7)多重赋值与匿名变量
package main //必须有一个main包
import "fmt"
//go函数可以返回多个值
func test() (a, b, c int) {
return 1, 2, 3
}
func main() {
// a := 10
// b := 20
// c := 30
a, b := 10, 20
//交换2个变量的值
var tmp int
tmp = a
a = b
b = tmp
fmt.Printf("a = %d, b = %d\n", a, b)
// i := 10
// j := 20
i, j := 10, 20
i, j = j, i
fmt.Printf("i = %d, j = %d\n", i, j)
i = 10
j = 20
//_匿名变量,丢弃数据不处理, _匿名变量配合函数返回值使用,才有优势
tmp, _ = i, j
fmt.Println("tmp = ", tmp)
var c, d, e int
c, d, e = test() //return 1, 2, 3
fmt.Printf("c = %d, d = %d, e = %d\n", c, d, e)
_, d, e = test() //return 1, 2, 3
fmt.Printf("d = %d, e = %d\n", d, e)
}
Printf和Println的区别
package main //必须有一个main包
import "fmt"
func main() {
a := 10
//一段一段处理,自动加换行
fmt.Println("a = ", a)
//格式化输出, 把a的内容放在%d的位置
// "a = 10\n" 这个字符串输出到屏幕,"\n"代表换行符
fmt.Printf("a = %d\n", a)
b := 20
c := 30
fmt.Println("a = ", a, ", b = ", b, ", c = ", c)
fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
}
fmt包的格式化输出输入
printf的使用方法,以下为输出例子1
import "fmt"
func main() {
a := 10
b := "abc"
c := 'a'
d := 3.14
//%T操作变量所属类型
fmt.Printf("%T, %T, %T, %T\n", a, b, c, d)
//%d 整型格式
//%s 字符串格式
//%c 字符个数
//%f 浮点型个数
fmt.Printf("a = %d, b = %s, c = %c, d = %f\n", a, b, c, d)
//%v自动匹配格式输出
fmt.Printf("a = %v, b = %v, c = %v, d = %v\n", a, b, c, d)
}
输出例子2
//整型
a := 15
fmt.Printf("a = %b\n", a) //a = 1111
fmt.Printf("%%\n") //只输出一个%
//字符
ch := 'a'
fmt.Printf("ch = %c, %c\n", ch, 97) //a, a
//浮点型
f := 3.14
fmt.Printf("f = %f, %g\n", f, f) //f = 3.140000, 3.14
fmt.Printf("f type = %T\n", f) //f type = float64
//复数类型
v := complex(3.2, 12)
fmt.Printf("v = %f, %g\n", v, v) //v = (3.200000+12.000000i), (3.2+12i)
fmt.Printf("v type = %T\n", v) //v type = complex128
//布尔类型
fmt.Printf("%t, %t\n", true, false) //true, false
//字符串
str := "hello go"
fmt.Printf("str = %s\n", str) //str = hello go
输入例子1
var v int
fmt.Println("请输入一个整型:")
fmt.Scanf("%d", &v)
//fmt.Scan(&v)
fmt.Println("v = ", v)
输入例子2
package main //必须有一个main包
import "fmt"
func main() {
var a int //声明变量
fmt.Printf("请输入变量a: ")
//阻塞等待用户的输入
//fmt.Scanf("%d", &a) //别忘了&
fmt.Scan(&a)
fmt.Println("a = ", a)
}
格式说明
常量
在Go语言中,常量是指编译期间就已知且不可改变的值。常量可以是数值类型(包括整型、浮点型和复数类型)、布尔类型、字符串类型等。
(1)字面常量(常量值)
所谓字面常量(literal),是指程序中硬编码的常量,如:
123
3.1415 // 浮点类型的常量
3.2+12i // 复数类型的常量
true // 布尔类型的常量
"foo" // 字符串常量
(2)常量定义
const Pi float64 = 3.14
const zero = 0.0 // 浮点常量, 自动推导类型
const ( // 常量组
size int64 = 1024
eof = -1 // 整型常量, 自动推导类型
)
const u, v float32 = 0, 3 // u = 0.0, v = 3.0,常量的多重赋值
const a, b, c = 3, 4, "foo"
// a = 3, b = 4, c = "foo" //err, 常量不能修改
(3)常量的使用
package main //必须有一个main包
import "fmt"
func main() {
//变量:程序运行期间,可以改变的量, 变量声明需要var
//常量:程序运行期间,不可以改变的量,常量声明需要const
const a int = 10
//a = 20 //err, 常量不允许修改
fmt.Println("a = ", a)
const b = 11.2 //没有使用:=
fmt.Printf("b type is %T\n", b)
fmt.Println("b = ", b)
}
(4)iota枚举
常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。
在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一。
const (
x = iota // x == 0
y = iota // y == 1
z = iota // z == 2
w // 这里隐式地说w = iota,因此w == 3。其实上面y和z可同样不用"= iota"
)
const v = iota // 每遇到一个const关键字,iota就会重置,此时v == 0
const (
h, i, j = iota, iota, iota //h=0,i=0,j=0 iota在同一行值相同
)
const (
a = iota //a=0
b = "B"
c = iota //c=2
d, e, f = iota, iota, iota //d=3,e=3,f=3
g = iota //g = 4
)
const (
x1 = iota * 10 // x1 == 0
y1 = iota * 10 // y1 == 10
z1 = iota * 10 // z1 == 20
)
package main //必须有一个main包
import "fmt"
func main() {
//1、iota常量自动生成器,每个一行,自动累加1
//2、iota给常量赋值使用
const (
a = iota //0
b = iota //1
c = iota //2
)
fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
//3、iota遇到const,重置为0
const d = iota
fmt.Printf("d = %d\n", d)
//4、可以只写一个iota
const (
a1 = iota //0
b1
c1
)
fmt.Printf("a1 = %d, b1 = %d, c1 = %d\n", a1, b1, c1)
//5、如果是同一行,值都一样
const (
i = iota
j1, j2, j3 = iota, iota, iota
k = iota
)
fmt.Printf("i = %d, j1 = %d, j2 = %d, j3 = %d, k = %d\n", i, j1, j2, j3, k)
}
(5)多个变量或常量定义
package main //必须有一个main包
import "fmt"
func main() {
//不同类型变量的声明(定义)
// var a int = 1
// var b float64 = 2.0
// var (
// a int = 1
// b float64 = 2.0
// )
//可以自动推导类型
var (
a = 1
b = 2.0
)
a, b = 10, 3.14
fmt.Println("a = ", a)
fmt.Println("b = ", b)
//选中代码,按ctrl+\, 注释和取消注释代码的快捷键
// const i int = 10
// const j float64 = 3.14
// const (
// i int = 10
// j float64 = 3.14
// )
//可以自动推导类型
const (
i = 10
j = 3.14
)
fmt.Println("i = ", i)
fmt.Println("j = ", j)
}
基础数据类型
(1)布尔类型
package main //必须有一个main包
import "fmt"
func main() {
//1、声明变量, 没有初始化,零值(初始值)为false
var a bool
fmt.Println("a0 = ", a)
a = true
fmt.Println("a = ", a)
//2、自动推导类型
var b = false
fmt.Println("b = ", b)
c := false
fmt.Println("c = ", c)
}
(2)整型
var v1 int32
v1 = 123
v2 := 64 // v1将会被自动推导为int类型
(3)浮点型
package main //必须有一个main包
import "fmt"
func main() {
//声明变量
var f1 float32
f1 = 3.14
fmt.Println("f1 = ", f1)
//自动推导类型
f2 := 3.14
fmt.Printf("f2 type is %T\n", f2) //f2 type is float64
//float64存储小数比float32更准确
}
(4)字符
实际上byte也是整型
package main //必须有一个main包
import "fmt"
func main() {
var ch byte //声明字符类型
ch = 97
//fmt.Println("ch = ", ch)
//格式化输出,%c以字符方式打印,%d以整型方式打印
fmt.Printf("%c, %d\n", ch, ch)
ch = 'a' //字符, 单引号
fmt.Printf("%c, %d\n", ch, ch)
//大写转小写,小写转大写, 大小写相差32,小写大
fmt.Printf("大写:%d, 小写:%d\n", 'A', 'a')
fmt.Printf("大写转小写:%c\n", 'A'+32)
fmt.Printf("小写转大写:%c\n", 'a'-32)
//'\'以反斜杠开头的字符是转义字符, '\n'代表换行
fmt.Printf("hello go%c", '\n')
fmt.Printf("hello itcast")
}
(5)字符串
package main //必须有一个main包
import "fmt"
func main() {
var str1 string //声明变量
str1 = "abc"
fmt.Println("strl = ", str1)
//自动推导类型
str2 := "mike"
fmt.Printf("str2 类型是 %T\n", str2)
//内建函数,len()可以测字符串的长度,有多少个字符
fmt.Println("len(str2) = ", len(str2))
}
string类型和byte类型的区别
package main //必须有一个main包
import "fmt"
func main() {
var ch byte
var str string
//字符
//1、单引号
//2、字符,往往都只有一个字符,转义字符除外'\n'
ch = 'a'
fmt.Println("ch =", ch)
//字符串
//1、双引号
//2、字符串有1个或多个字符组成
//3、字符串都是隐藏了一个结束符,'\0'
str = "a" // 由'a'和'\0'组成了一个字符串
fmt.Println("str = ", str)
str = "hello go"
//只想操作字符串的某个字符,从0开始操作
fmt.Printf("str[0] = %c, str[1] = %c\n", str[0], str[1])
}
(6)复数
package main //必须有一个main包
import "fmt"
func main() {
var t complex128 //声明
t = 2.1 + 3.14i //赋值
fmt.Println("t = ", t)
//自动推导类型
t2 := 3.3 + 4.4i
fmt.Printf("t2 type is %T\n", t2)
//通过内建函数,取实部和虚部
fmt.Println("real(t2) = ", real(t2), ", imag(t2) = ", imag(t2))
}
类型转换
Go语言中不允许隐式转换,所有类型转换必须显式声明,而且转换只能发生在两种相互兼容的类型之间。
package main //必须有一个main包
import "fmt"
func main() {
//这种不能转换的类型,叫不兼容类型
var flag bool
flag = true
fmt.Printf("flag = %t\n", flag)
//bool类型不能转换为int
//fmt.Printf("flag = %d\n", int(flag))
//0就是假,非0就是真
//整型也不能转换为bool
//flag = bool(1)
var ch byte
ch = 'a' //字符类型本质上就是整型
var t int
t = int(ch) //类型转换,把ch的值取出来后,转成int再给t赋值
fmt.Println("t = ", t)
}
类型别名
package main //必须有一个main包
import "fmt"
func main() {
//给int64起一个别名叫bigint
type bigint int64
var a bigint // 等价于var a int64
fmt.Printf("a type is %T\n", a)
type (
long int64
char byte
)
var b long = 11
var ch char = 'a'
fmt.Printf("b = %d, ch = %c\n", b, ch)
}
运算符
package main //必须有一个main包
import "fmt"
func main() {
fmt.Println("4 > 3 结果:", 4 > 3)
fmt.Println("4 != 3 结果:", 4 != 3)
fmt.Println("!(4 > 3) 结果:", !(4 > 3))
fmt.Println("!(4 != 3) 结果:", !(4 != 3))
//&& 与, 并且,左边右边都为真,结果才为真, 其它都为假
fmt.Println("true && true 结果:", true && true)
fmt.Println("true && false 结果:", true && false)
// ||, 或者, 左边右边都为假,结果才为假,其它都为真
fmt.Println("true || false 结果:", true || false)
fmt.Println("false || false 结果:", false || false)
a := 11
fmt.Println("0 <= a && a <= 10 结果为:", 0 <= a && a <= 10)
}
if使用
package main //必须有一个main包
import "fmt"
func main() {
s := "屌丝"
//if和{就是条件,条件通常都是关系运算符
if s == "王思聪" { //左括号和if在同一行
fmt.Println("左手一个妹子,右手一个大妈")
}
//if支持1个初始化语句, 初始化语句和判断条件以分号分隔
if a := 10; a == 10 { //条件为真,指向{}语句
fmt.Println("a == 10")
}
}
if_elseif_else的使用
package main //必须有一个main包
import "fmt"
func main() {
//1
a := 10
if a == 10 {
fmt.Println("a == 10")
} else { //else后面没有条件
fmt.Println("a != 10")
}
//2
if a := 10; a == 10 {
fmt.Println("a == 10")
} else { //else后面没有条件
fmt.Println("a != 10")
}
//3
a = 8
if a == 10 {
fmt.Println("a == 10")
} else if a > 10 {
fmt.Println("a > 10")
} else if a < 10 {
fmt.Println("a < 10")
} else {
fmt.Println("这是不可能的")
}
//4
if a := 8; a == 10 {
fmt.Println("a == 10")
} else if a > 10 {
fmt.Println("a > 10")
} else if a < 10 {
fmt.Println("a < 10")
} else {
fmt.Println("这是不可能的")
}
}
多个if和if_elseif的区别
package main //必须有一个main包
import "fmt"
func main() {
//这种好
a := 10
if a == 10 {
fmt.Println("a == 10")
} else if a > 10 {
fmt.Println("a > 10")
} else if a < 10 {
fmt.Println("a < 10")
}
b := 10
if b == 10 {
fmt.Println("b == 10")
}
if b > 10 {
fmt.Println("b > 10")
}
if b < 10 {
fmt.Println("b < 10")
}
}
switch使用
package main //必须有一个main包
import "fmt"
func main() {
var num int
fmt.Printf("请按下楼层:")
fmt.Scan(&num)
switch num { //switch后面写的是变量本身
case 1:
fmt.Println("按下的是1楼")
//break //go语言保留了break关键字,跳出switch语言, 不写,默认就包含
fallthrough //不跳出switch语句,后面的无条件执行
case 2:
fmt.Println("按下的是2楼")
//break
fallthrough
case 3:
fmt.Println("按下的是3楼")
//break
fallthrough
case 4:
fmt.Println("按下的是4楼")
//break
fallthrough
default:
fmt.Println("按下的是xxx楼")
}
}
补充用法
package main //必须有一个main包
import "fmt"
func main() {
//支持一个初始化语句, 初始化语句和变量本身, 以分号分隔
switch num := 4; num { //switch后面写的是变量本身
case 1:
fmt.Println("按下的是1楼")
case 2:
fmt.Println("按下的是2楼")
case 3, 4, 5:
fmt.Println("按下的是yyy楼")
case 6:
fmt.Println("按下的是4楼")
default:
fmt.Println("按下的是xxx楼")
}
score := 85
switch { //可以没有条件
case score > 90: //case后面可以放条件
fmt.Println("优秀")
case score > 80: //case后面可以放条件
fmt.Println("良好")
case score > 70: //case后面可以放条件
fmt.Println("一般")
default:
fmt.Println("其它")
}
}
for使用
package main //必须有一个main包
import "fmt"
func main() {
//for 初始化条件 ; 判断条件 ; 条件变化 {
//}
//1+2+3 …… 100累加
sum := 0
//1) 初始化条件 i := 1
//2) 判断条件是否为真, i <= 100, 如果为真,执行循环体,如果为假,跳出循环
//3) 条件变化 i++
//4) 重复2, 3, 4
for i := 1; i <= 100; i++ {
sum = sum + i
}
fmt.Println("sum = ", sum)
}
range使用
package main //必须有一个main包
import "fmt"
func main() {
str := "abc"
//通过for打印每个字符
for i := 0; i < len(str); i++ {
fmt.Printf("str[%d]=%c\n", i, str[i])
}
//迭代打印每个元素,默认返回2个值: 一个是元素的位置,一个是元素本身
for i, data := range str {
fmt.Printf("str[%d]=%c\n", i, data)
}
for i := range str { //第2个返回值,默认丢弃,返回元素的位置(下标)
fmt.Printf("str[%d]=%c\n", i, str[i])
}
for i, _ := range str { //第2个返回值,默认丢弃,返回元素的位置(下标)
fmt.Printf("str[%d]=%c\n", i, str[i])
}
}
break和continue的区别
package main //必须有一个main包
import "fmt"
import "time"
func main() {
i := 0
for { //for后面不写任何东西,这个循环条件永远为真,死循环
i++
time.Sleep(time.Second) //演示1s
if i == 5 {
//break //跳出循环,如果嵌套多个循环,跳出最近的那个内循环
continue //跳过本次循环,下一次继续
}
fmt.Println("i = ", i)
}
}
goto使用
package main //必须有一个main包
import "fmt"
func main() {
//break //break is not in a loop, switch, or select
//continue//continue is not in a loop
//goto可以用在任何地方,但是不能夸函数使用
fmt.Println("11111111111111")
goto End //goto是关键字, End是用户起的名字, 他叫标签
fmt.Println("222222222222222")
End:
fmt.Println("3333333333333")
}
参考链接
Go语言官网:https://golang.org/
go中文社区:https://studygolang.com
go中文在线文档:https://studygolang.com/pkgdoc