安装
ubuntu18安装go
下载:https://studygolang.com/dl
解压缩
将解压后的文件夹,放到自己平常的安装包位置,并设置0777权限
配置go环境变量
GOROOT是系统上安装Go软件包的位置GOPATH是工作目录的位置
创建工作目录,我选择创建在/home/lxgzhw目录
修改环境变量
添加以下内容。同时也在GOPATH目录下创建src和bin目录
使用一下命令使环境变量生效,并可以查看环境变量
测试
tar -zxvf go1.12.1.linux-amd64.tar.gz
sudo cp -rf go /usr/local
cd /usr/local
sudo chmod -R 0777 go
cd
mkdir GOPATH
sudo chmod -R 0777 GOPATH
sudo vim ~/.bashrc
export GOROOT=/usr/local/go
export GOPATH=/home/lxgzhw/GOPATH
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
source ~/.bashrc
export
go version
修改GOPROXY,这一步是为了解决go get安装的时候time out错误问题
基础语法
第一个程序
在GOPATH/src下创建一个目录 hello,并在其中创建hello.go
运行方式
变量和标识符
注意
标识符不能以数字开头标识符不能是系统关键字标识符中不要用特殊符号
定义变量的方式一
示例
go env -w GOPROXY=https://goproxy.cn,direct
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
go run hello.go
var 变量名 变量类型
package main
import "fmt"
func main() {
var num int
num = 20
fmt.Println("我会", num, "门编程语言。")
}
数据类型
常用的数据类型有
整数:int浮点数:float字符串:string布尔值:bool
示例
自动推导数据类型
go语言可以自动推导数据类型,主要有以下两种方法
示例1: var 变量名 变量类型 = 变量值
package main
import "fmt"
func main() {
// 整数
var num int
num = 10
fmt.Println("这是一个整数:", num)
// 浮点数
var fnum float64
fnum = 33.3333
fmt.Println("这是一个浮点数:", fnum)
// 字符串
var str string
str = "hello world"
fmt.Println("这是一个字符串:", str)
// 布尔值
var flag bool
flag = true
fmt.Println("这是一个布尔值:", flag)
}
package main
import "fmt"
func main() {
// 整数
var num int = 10
示例2: var 变量名 = 变量值
示例3:变量名 := 变量值
fmt.Println("这是一个整数:", num)
// 浮点数
var fnum float64 = 33.3333
fmt.Println("这是一个浮点数:", fnum)
// 字符串
var str string = "hello world"
fmt.Println("这是一个字符串:", str)
// 布尔值
var flag bool = true
fmt.Println("这是一个布尔值:", flag)
}
package main
import "fmt"
func main() {
// 整数
var num = 10
fmt.Println("这是一个整数:", num)
// 浮点数
var fnum = 33.3333
fmt.Println("这是一个浮点数:", fnum)
// 字符串
var str = "hello world"
fmt.Println("这是一个字符串:", str)
// 布尔值
var flag = true
fmt.Println("这是一个布尔值:", flag)
}
package main
import "fmt"
func main() {
// 整数
num := 10
fmt.Println("这是一个整数:", num)
// 浮点数
多变量赋值
示例1:变量1,变量2,变量3 := 变量1的值,变量2的值,变量3的值
示例2
fnum := 33.3333
fmt.Println("这是一个浮点数:", fnum)
// 字符串
str := "hello world"
fmt.Println("这是一个字符串:", str)
// 布尔值
flag := true
fmt.Println("这是一个布尔值:", flag)
}
package main
import "fmt"
func main() {
// 方法1
var a1, a2, a3 int
a1, a2, a3 = 11, 22, 33
fmt.Println(a1, a2, a3)
fmt.Println("---------------------------")
// 方法2
a11, a22, a33 := 11, 22, 33
fmt.Println(a11, a22, a33)
}
package main
import "fmt"
var (
name string
age int
)
func main() {
name = "zhangsan"
age = 33
fmt.Println(name, age)
}
变量内存地址
示例1:得出结论 "基本数据类型的变量,地址值是固定的,修改变量的值,内存地址不会改变"
示例2:得出结论 "相同类型的数据,值也相同,如果赋值给不同的变量,这两个变量的内存地址是不一样的"
示例3:得出结论 "基础类型的变量,把一个变量赋值给另一个变量,两个变量的内存地址是不一样的"
package main
import "fmt"
var (
name string
age int
)
func main() {
name = "zhangsan"
age = 33
fmt.Println(name, age)
// 打印内存地址
fmt.Println(&name, &age)
fmt.Println("----------------------------")
name = "lisi"
age = 44
fmt.Println(name, age)
// 打印内存地址
fmt.Println(&name, &age)
}
package main
import "fmt"
func main() {
s1 := "aaa"
s2 := "aaa"
fmt.Println(s1, &s1)
fmt.Println(s2, &s2)
fmt.Println("----------------------")
}
不同进制的表示
常见的进制
十进制:正常的数八进制:0开头十六进制:0x开头
示例:结论 "相同的数字,八进制最小,十进制正常,十六进制最大"
常量
示例1:常量的定义,使用 const关键字定义常量。常量名应该使用全大写
package main
import "fmt"
func main() {
s1 := "aaa"
s2 := s1
fmt.Println(s1, &s1)
fmt.Println(s2, &s2)
fmt.Println("----------------------")
}
package main
import "fmt"
func main() {
// 十进制表示
fmt.Println("我要学习", 33, "门新技术")
// 八进制表示
fmt.Println("我要学习", 033, "门新技术")
// 十六进制表示
fmt.Println("我要学习", 0x33, "门新技术")
}
package main
import "fmt"
func main() {
const PI = 3.1415926
fmt.Println("圆周率:", PI)
}
示例2:连续定义多个变量
示例3:使用 "iota"连续赋值多个常量
示例4:iota的值和定义位置有关
package main
import "fmt"
func main() {
const (
A = 1
B = 2
C = 3
)
fmt.Println("A:", A, "B:", B, "C:", C)
}
package main
import (
"fmt"
)
func main() {
const (
a = iota
b = iota
c = iota
d = iota
)
fmt.Println(a, b, c, d)
}
package main
import (
"fmt"
)
func main() {
const (
a = iota
b = iota
c = iota
d = iota
)
fmt.Println(a, b, c, d)
fmt.Println("--------------------------")
const (
变量的内存大小
示例:查看变量的内存大小,变量的内存大小单位是"字节"
运算符
简介
go语言中常见的运算符有
算术运算符比较运算符逻辑运算符
算术运算符
示例1:加减乘除四则运算
a1 = 33
b1 = 44
c1 = iota
d1 = iota
)
fmt.Println(a1, b1, c1, d1)
fmt.Println("--------------------------")
}
package main
import (
"fmt"
"unsafe"
)
func main() {
num := 10
fmt.Println("查看变量的内存大小:", unsafe.Sizeof(num))
}
package main
import (
"fmt"
)
func main() {
a := 10
b := 20
fmt.Println(a + b)
示例2:取余,一般用于判断奇数和偶数
示例3:整除,会去掉小数部分。go语言中的除数结果,默认取的就是整除结果。
自增自减运算符
示例1:自增运算符,调用后原来的数自动加1
fmt.Println(a - b)
fmt.Println(a * b)
fmt.Println(a / b)
}
package main
import (
"fmt"
)
func main() {
a := 11
b := 22
// 奇数
fmt.Println(a % 2)
fmt.Println(a%2 == 1)
// 偶数
fmt.Println(b % 2)
fmt.Println(b%2 == 0)
}
package main
import (
"fmt"
)
func main() {
a := 11
b := 3
fmt.Println(a / b)
}
package main
import (
"fmt"
)
func main() {
示例2:自减运算符,调用后原来的数自动减去1
比较运算符
比较运算符用于判断大小,常见的有
大于: >
小于: <
等于: ==
不等于: !=
大于等于: >=
小于等于: <=
示例1:比较运算符的基本使用
a := 11
a++
fmt.Println(a)
fmt.Println("---------------------------")
b := 22.22
b++
fmt.Println(b)
}
package main
import (
"fmt"
)
func main() {
a := 11
a--
fmt.Println(a)
fmt.Println("---------------------------")
b := 22.22
b--
fmt.Println(b)
}
package main
import (
"fmt"
)
func main() {
a := 11
b := 22
fmt.Println(a > b)
fmt.Println(a >= b)
逻辑运算符
逻辑运算符用于组合多个比较表达式,用于运算多个比较的结果,常见的有
与: &&
或: ||
非: !
示例1:判断1999年是否为闰年
位运算符
位运算符是针对二进制进行运算的特殊符号,常用的有
按位与: &
按位或: |
按位异或: ^
左移运算符: <<
右移运算符: >>
进制运算特点
fmt.Println(a < b)
fmt.Println(a <= b)
fmt.Println(a == b)
fmt.Println(a != b)
}
package main
import (
"fmt"
)
func main() {
year := 1999
flag := year%4 == 0 && year%100 != 00 || year%400 == 0
fmt.Println("1999年是闰年吗? ", flag)
}
十进制:
123 = 1*10^2 + 2*10^1 + 3*10^0
= 100 + 20 + 3
= 123
897 = 8*10^2 + 9*10^1 + 7*10^0
= 800 + 90 + 7
ijk = i*10^2 + j*10^2 + k*10^0
示例1:按位与运算
运算规则:只有两个数的二进制同时为1,结果才为1,否则为0示例
使用go语言进行计算并验证
示例2:按位或运算
运算规则:参加运算的两个数只要两个数中的一个为1,结果就为1示例
十进制数的运算特点:从左到右,每个数*10^(数个数-1-索引)
二进制:
110 = 1*2^2 + 1*2^1 + 0*2^0
= 4 + 2 + 0
= 6
二进制数运算特点:从左到右,这个数*2^(数个数-1-索引)
示例:5&6
5的二进制数:101
6的二进制数:110
101
110
转换后为
100
然后将二进制转换为十进制
100 = 1*2^2 + 0*2^1 + 0*2^0
= 4 + 0 + 0
= 4
所以: 5&6 == 4
package main
import (
"fmt"
)
func main() {
// 按位与运算
fmt.Println(5 & 6)
}
示例:5|6
5的二进制数:101
6的二进制数:110
使用go语言计算并校验
示例3:异或运算
运算规则:参加运算的两个数,如果两个相应位为"异"(值不同),则该位结果为1,否则为0。示例
使用go语言计算并校验
101
110
转换后为
111
然后将二进制转换为十进制
100 = 1*2^2 + 1*2^1 + 1*2^0
= 4 + 2 + 1
= 7
所以: 5|6 == 7
package main
import (
"fmt"
)
func main() {
// 按位或运算
fmt.Println(5 | 6)
}
示例:5^6
5的二进制数:101
6的二进制数:110
101
110
转换后为
011
然后将二进制转换为十进制
100 = 0*2^2 + 1*2^1 + 1*2^0
= 0 + 2 + 1
= 3
所以: 5^6 == 3
示例4:左移运算
运算规则:将一个运算对象的各二进制位全部左移若干位(左边的二进制丢弃,右边补0)说明:用来将一个数的各二进制位全部左移N位,右补0示例
使用go语言计算并校验
示例5:右移运算
运算规则:将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0说明:对于右移,直观的理解为,对于正数来说,右1移相当于除以2(但效率比除法高)示例
package main
import (
"fmt"
)
func main() {
// 按位异或运算
fmt.Println(5 ^ 6)
}
示例:5<<2
5的二进制数:101
左移2:10100
转换为十进制
10100 = 1*2^4 + 0*2^3 + 1*2^2 + 0*2^1 + 0*2^0
= 16 + 0 + 4 + 0 + 0
= 20
所以:5<<2 == 20
package main
import (
"fmt"
)
func main() {
fmt.Println(5 << 2)
}
使用go语言计算并校验
示例
示例:5>>2
5的二进制数:101
右移2:001
转换为十进制
001 = 0*2^2 + 0*2^1 + 1*2^0
= 0 + 0 + 1
= 1
所以:5>>2 == 1
package main
import (
"fmt"
)
func main() {
fmt.Println(5 >> 2)
}
示例:11>>2
第一步:求11的二进制数
十进制整数转换为二进制整数十进制整数转换为二进制整数采用"除2取余,逆序排列"法。具体做法是:用2整
除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时
为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列
起来。
11 / 2 == 5余1---1
5 / 2 == 2余1---11
2 / 2 == 1余0---011
1 / 2 == 0余1---1011
所以:11的二进制数是0b1011
验证:
111 = 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0
= 8 + 0 + 2 + 1
= 11
第二步:右移
11 >> 2 == 1011 变为 0011 == 0b10
第三步:将二进制数转换为十进制数
0b11 = 1*2^1 + 0*2^0
= 2 + 0
= 2
所以:11>>2 = 2
使用go计算并验证
赋值运算符
常见的赋值运算符
赋值: =
推导类型赋值: :=
运算并赋值: +=、-=、*=、/=、%=
示例
取地址运算符
常见的地址运算符有两个
取地址运算符: &
间接访问地址运算符: *
示例1:通过内存地址修改变量的值
package main
import (
"fmt"
)
func main() {
fmt.Println(11 >> 2)
}
package main
import (
"fmt"
)
func main() {
// 推导类型并赋值
num := 33
fmt.Println(num)
fmt.Println("-----------------------")
// 计算并赋值
num += 44
fmt.Println(num)
}
package main
类型转换
整数转浮点数
示例1
字符串转整数
示例1
import "fmt"
func main() {
num := 10
// 修改数据的方法:1.直接修改变量的值
num = 33
fmt.Println(num)
fmt.Println("---------------------")
// 修改数据的方法:1.直接修改变量内存地址的值
// &num:获取内存地址
// *(&num):操作指定内存地址的值
*(&num) = 44
fmt.Println(num)
}
package main
import "fmt"
func main() {
num := 18
fmt.Println(num)
// 转换为浮点型
fmt.Println(float64(num))
}
package main
import (
"fmt"
"strconv"
)
func main() {
s := "12345"
// 字符串转整数
num, err := strconv.Atoi(s)
if err != nil {
整数转字符串
示例1
语句
if语句
语法
示例1
fmt.Println(err)
}
fmt.Println(num)
}
package main
import (
"fmt"
"strconv"
)
func main() {
num := 12345
// 整数转字符串
s := strconv.Itoa(num)
fmt.Println(s)
}
if(条件){
条件满足执行的语句
}
package main
import "fmt"
func main() {
age := 33
if age > 30 {
fmt.Println("都三十岁的人了。。。")
}
}
if…else语句
语法
示例1
if嵌套语句
语法
示例1:女神去相亲,定了一些择偶标准
if(条件){
条件满足执行的语句
}else{
条件不满足执行的语句
}
package main
import "fmt"
func main() {
age := 23
if age > 30 {
fmt.Println("都三十岁的人了。。。")
} else {
fmt.Println("三十而立,还早呢。。。")
}
}
if(条件){
if(条件){
条件都满足执行的语句
}
}
package main
import "fmt"
func main() {
gender := "男"
age := 23
money := 1000000
if gender == "男" {
fmt.Println("是个男的,可以考虑。。。")
if age < 30 {
fmt.Println("年龄没超过30,还不错,年轻。。。")
if money > 300000 {
示例2:女神相亲
if…else if…else语句
语法
fmt.Println("超过30万的存款,可以了,就他了。。。")
}
}
}
}
package main
import "fmt"
func main() {
// 女神相亲,将相亲对象分为:屌丝,备胎,高富帅
// 要求财富:100万
// 张三财富:10万
girl_need_money := 1000000
zhangsan_money := 100000
// 女神要求身高:1756
// 张三身高:188
girl_need_height := 175
zhangsan_height := 188
// 张三做生意赚钱了,身价翻了好多倍
zhangsan_money *= 20
// 如果张三财富不满足,就不能当备胎
if zhangsan_money < girl_need_money {
fmt.Println("张三不能当备胎")
} else {
fmt.Println("张三可以当备胎了。。。")
if zhangsan_height > girl_need_height {
fmt.Println("张三抱得美人归。。。。")
}
}
}
示例1:判断今天是星期几
switch语句
语法
if(条件1){
...
}else if(条件2){
...
}else if(条件3){
...
}...{
...
}else{
...
}
package main
import "fmt"
func main() {
weekDay := 3
if weekDay == 1 {
fmt.Println("星期一")
} else if weekDay == 2 {
fmt.Println("星期二")
} else if weekDay == 3 {
fmt.Println("星期三")
} else if weekDay == 4 {
fmt.Println("星期四")
} else if weekDay == 5 {
fmt.Println("星期五")
} else if weekDay == 6 {
fmt.Println("星期六")
} else if weekDay == 7 {
fmt.Println("星期天")
} else {
fmt.Println("错误的周日期时间")
}
}
示例1:判断月份属于哪个季节
示例2:使用switch判断接口类型
switch 变量{
case 值1:
...
case 值2:
...
...
default:
...
}
package main
import "fmt"
func main() {
month := 4
switch month {
case 3, 4, 5:
fmt.Println("春天")
break
case 6, 7, 8:
fmt.Println("春天")
break
case 9, 10, 11:
fmt.Println("春天")
break
case 12, 1, 2:
fmt.Println("春天")
break
default:
fmt.Println("错误的月份")
}
}
package main
import "fmt"
func main() {
//var x interface{} //接口语法
var x interface{}
switch i := x.(type) { //抓取类型
case int:
fmt.Println("整数类型", i)
case string:
for语句
示例1:大于10次"书山有路勤为径,学海无涯苦作舟。"
示例2:一直在控制台大于"坚持每天进步一点点。"
示例3:大于从1到100
fmt.Println("字符串类型", i)
case bool:
fmt.Println("布尔类型", i)
default:
fmt.Println("未知类型", i)
}
}
package main
import "fmt"
func main() {
var times = 10
//var i int
//循环10次
for i := 0; i < times; i++ {
fmt.Println("书山有路勤为径,学海无涯苦作舟。", i)
}
}
package main
import "fmt"
func main() {
for {
fmt.Println("坚持每天进步一点点。")
}
}
示例4:遍历数组
break语句
示例1:终止循环
package main
import "fmt"
func main() {
var a = 1
var b = 101
for a < b { //相当于其他语句while
fmt.Print(a, " ")
a++
}
}
package main
import "fmt"
func main() {
numbers := [5]int{11, 12, 13, 14, 15} //数组
// [5]代表5个元素, int整数类型 {1,2,3,4,5} 初始化数组的数据
fmt.Println(numbers)
for i, number := range numbers { //range取得数组索引与元素
fmt.Println(i, number) //i代表索引,number代表数组元素
}
}
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
fmt.Println(i)
if i == 4 {
break //break结束整个循环,终止
}
}
}
continue语句
示例1:跳过某次循环
循环语句嵌套
示例1:循环语句嵌套的基本执行流程,外层循环一次,内层整个循环
goto语句
示例1:跳转到指定位置
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
if i == 4 {
continue //continue结束本次循环,没有打印4
}
fmt.Println(i)
}
}
package main
import "fmt"
func main() {
//嵌套循环,i循环一次,j循环10次,
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
fmt.Print(i, j, " ")
}
fmt.Println()
}
}
package main
import "fmt"
func main() {
goto LOOP
LOOP:
fmt.Println("你妹") //goto就是跳转,用不好就是死循环
}
示例2:goto语句实现循环
示例3:goto实现死循环
字符串
基本用法
示例1:执行系统指令
示例2:字符串格式化
package main
import "fmt"
func main() {
var i = 0
AK:
for i < 10 { //goto实现循环
i += 1
fmt.Println(i)
goto AK
}
}
package main
import "fmt"
func main() {
LOOP:
fmt.Println("你妹") //goto就是跳转,用不好就是死循环
goto LOOP
}
package main
import (
"fmt"
"os/exec"
)
func main() {
var cmd = exec.Command("mspaint") //字符串执行系统指令
fmt.Println(cmd.Run()) //打印执行的返回值
}
示例3:字符串的拼接和合并
格式化字符串
示例1:整数前面补0和指定小数位长度
package main
import (
"fmt"
)
func main() {
var cmd = "notepad"
fmt.Println(cmd) //打印字符串 \n换行符
fmt.Printf("命令是\n是%s\n\n", cmd) //字符串格式化
for i := 0; i < len(cmd); i++ {
fmt.Printf("%c\n-----------", cmd[i]) //打印字符
fmt.Println(cmd[i]) //打印字符编号
}
}
package main
import (
"fmt"
"strings"
)
func main() {
// 字符串可以做拼接
var mystr = "hello" + "world"
fmt.Println(mystr) //字符串加法
fmt.Println("--------------------------")
var newstr = []string{"aaa", "bbb"} //字符串数组的归并
fmt.Println(strings.Join(newstr, "#"))
}
package main
import (
"fmt"
)
func main() {
// 指定整数长度,不足在前面补0
fmt.Printf("乐乐有%06d个备胎\n", 10)
// 指定小数位
fmt.Printf("乐乐期望的男朋友身高是%.2f米\n", 1.89)
// 打印字符串
fmt.Printf("乐乐讨厌的备胎是%s\n", "张洪杰")
}
函数
基本使用
函数参数
示例1:修改基本类型变量的值
普通变量作为参数,无法直接修改。函数参数存在副本机制,修改参数的值,不会直接对原本的数据产生修改。
package main
import (
"fmt"
)
//func 函数, add 函数名 (a 参数 int 参数类型,b int ) int返回类型 {}
func add(a int, b int) int {
return a + b //返回的数据
}
//函数的参数,返回值一般都需要指定类型
func addSub(a int, b int) (int, int) {
return a + b, a - b //返回多个数据
}
func main() {
// 调用返回值为一个数的函数
var c = add(1, 2)
fmt.Println(c)
fmt.Println("-------------------------")
// 调用返回值为多个数的函数
var x, y = addSub(10, 3) //返回多个数据
fmt.Println(x, y)
}
package main
import (
"fmt"
)
//函数参数存在副本机制,地址不一样,传递参数无法修改数据
func changenum(num int) {
// 这里是创建了一个新的变量,而不是修改原来的值
num = 1000
fmt.Println("changenum", num, &num)
}
func main() {
地址值作为参数,能够通过内存直接修改变量的值
示例2:交换两个变量的值
var num = 100
changenum(num)
fmt.Println("main", num, &num)
}
package main
import (
"fmt"
)
//根据内存修改地址,外挂原理,传递地址改变原来数据
// *int 表示传一个int类型的指针
func changenump(ptr *int) {
// 通过指针修改该内存地址的值
*ptr = 1000 //取出地址的内容,赋值
fmt.Println("changenump", *ptr, &(*ptr))
}
func main() {
var num = 100
changenump(&num) //传递地址
fmt.Println("main", num, &num)
}
package main
import "fmt"
// 交换两个变量的值
func swap(a *int, b *int) {
*a, *b = *b, *a
}
func main() {
a := 10
b := 20
fmt.Println(a, b)
swap(&a, &b)
fmt.Println(a, b)
}
匿名函数
示例1:匿名函数的基本使用
函数作为返回值
示例1:函数作为返回值
package main
import "fmt"
//func 函数, add 函数名 (a 参数 int 参数类型,b int ) int返回类型 {}
func add(a int, b int) int {
return a + b //返回的数据
}
func main() {
//自定义一个函数变量初始化
// 匿名函数
var myfunc = func(a int, b int) int {
return a + b
}
fmt.Println(myfunc(1, 2))
fmt.Println(add(1, 2))
}
package main
import "fmt"
//func 函数, add 函数名 (a 参数 int 参数类型,b int ) int返回类型 {}
func add(a int, b int) int {
return a + b //返回的数据
}
func main() {
//返回一个函数 func() int
var myfunc = func() func() int {
fmt.Println("可以在内层函数执行之前,添加一些执行逻辑。。。。")
// 内层要返回的函数
return func() int {
return 10
}
}
// 直接调用,返回的是一个函数
fmt.Println(myfunc())
fmt.Println("-----------------------")
// 将返回的函数再次调用,得到结果
fmt.Println(myfunc()())
}
本文暂时没有评论,来添加一个吧(●'◡'●)