Skip to main content

基础

基础篇

go 语言第一个代码

package main

//package 文件所属的包
//行注释 可以注释一行

/*
块注释
可以注释多行
*/
import "fmt"

//import 导入包

//func 函数格式
//main 主函数 程序有且只有一个主函数
//() 函数参数
//{} 代码体
func main() {
//打印操作函数
fmt.Println("hello world")
fmt.Println("性感法师,在线讲课")
}

编译过程:

#编译并生成可执行程序
go build 源码文件.go
#编译生成可执行程序并运行
go run 源码文件.go

交叉编译:

  • CGO_ENAVLED 设置C和Go混合编程 0 不使用 1使用

  • GOOS 指定操作系统 Windows(windows) Linux(linux)MacOS(darwin) Unix(freebsd)

  • GOARCH 可执行程序的操作系统架构 386 amd64 arm

    Go语言函数帮助文档:

    go doc 包名
    go doc 包名.函数名

    Go语言测试工具:

    注意事项:

  • 文件名必须以 _test.go结尾

  • 函数名必须以Test开头 测试函数名首字母大写

  • 测试函数依次执行

    测试命令:

    go test -v 文件_test.go

    执行代码:

    package main

    import (
    "testing"
    "time"
    )

    func TestHelloWorld(t *testing.T) {
    timer := time.Now().UnixNano()
    t.Log(timer)
    }

    执行结果:

    === RUN   TestHelloWorld
    TestHelloWorld: 02测试_test.go:10: 1583567558611368000
    --- PASS: TestHelloWorld (0.00s)
    PASS
    ok command-line-arguments 2.648s

    RUN 执行函数

    PASS 测试方法通过 FAIL表示失败

    ok 执行花费时间

声明变量

变量声明规则:

  • 允许使用字母 数字 下划线

  • 不允许使用系统关键字

  • 不允许使用数组开头

  • 区分大小写

  • 见名知义

    驼峰式命名:

    大驼峰:每个单词首字母大写(public)可以被外部函数使用

    小驼峰:第一个单词首字母小写(private)可以在包内部使用


//用于声明变量,声明方式包括以下几种:
var name1 int64
var name2 = 15 //int 类型
//在func内可以使用简写等价,但是简写不可用于声明全局变量,即不能用于func外
name3 := 15
name4,name5,name6 := "a","b","c" //同时赋值给多个变量

类型转换

package main

import "fmt"

func main0101() {
//去市场买菜 黄瓜3.25元/斤 买5斤
price := 3.25 //float64
weight := 5 //int

//fmt.Printf("%T\n", price)
//fmt.Printf("%T\n", weight)
//数据类型(变量名)
//sum := price * float64(weight)//16.225
//将浮点型转成整型 可能丢失数据精度
//sum := int(price) * weight //15

//数据类型(表达式)
sum := int(price * float64(weight)) //16
fmt.Println(sum)
}

type int1 int
type int2 int

func main() {
//var a int8 = 123
//var b int = 234
//fmt.Println(int(a) + b)
//type rune = int32 两个数据类型可以计算
//ch := 'A' //rune ==int32
//var b int32 = 100
//fmt.Println(ch + b)
var a int1 = 123
var b int2 = 123

fmt.Println(a + int1(b))
}

派生数据类型

数组:

一组具有相同数据类型在内存中有序存储的数据集合

数组的长度在定义后不可以修改。

数组定义和使用:

func main0201() {
//数组定义和使用
//var 数组名 [元素个数]数据类型
//var arr [10]int//默认值为0
////使用数组名+下标进行数组初始化 下标是从0开始的到数组最大元素个数-1
//arr[0] = 123
//arr[-1] = 123 //err 数组下标越界

//var arr [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
//fmt.Println(arr)
//len(数组名) 计算数组元素个数
//fmt.Println(len(arr))

//遍历数组元素
//for i := 0; i < len(arr); i++ {
// fmt.Println(arr[i])
//}
//i index 下标 v value 值
for i, v := range arr {
fmt.Println(i, v)
}
}

数组内存存储:

func main() {
arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
for i := 0; i < len(arr); i++ {
//& 取地址运算符
fmt.Println(&arr[i])
}
}

切片:

一组具有相同数据类型在内存中有序存储的可扩容的数据集合

切片的定义和使用:

package main

import "fmt"

func main() {
//切片的定义和使用
//var 切片名 []数据类型
//var slice []int
//make([]数据类型,长度)
//var slice []int = make([]int, 10)
//slice[0] = 123
//fmt.Println(slice)

var slice []int
fmt.Println(len(slice)) //计算长度
fmt.Println(cap(slice)) //计算容量

//使用append对切片进行扩容
slice = append(slice, 1, 2, 3, 4, 5)
fmt.Println(len(slice)) //计算长度
fmt.Println(cap(slice)) //计算容量

//切片扩容为偶数的值 小于1024 为上一次的两倍 大于1024为上一次的1/4
fmt.Println(slice)
}

切片的截取:

func main0302() {
//切片的截取
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

//切片名[起始下标:结束下标:容量] 左闭右开 包含起始下标 不包含结束下标
//s := slice[2:7]
//fmt.Println(s)
//s:=slice[2:]
//fmt.Println(s)
//s:=slice[:5]
//fmt.Println(s)
s := slice[2:5:6] //实际容量=容量-起始下标
fmt.Println(s)

//fmt.Println(len(s))
//fmt.Println(cap(s))

s[0] = 333
//切片的截取 是将新的切片指向源切片的内存地址 修改一个会影响另外一个
fmt.Println(s)
fmt.Println(slice)

fmt.Println(unsafe.Sizeof(slice))
fmt.Println(unsafe.Sizeof(s))
}

切片的拷贝:

func main() {
slice := []int{1, 2, 3, 4, 5}

//s := slice
//s[2] = 333
//fmt.Println(s)
//fmt.Println(slice)
//在存储存储两个内容完全相同 但是不会相互影响
s := make([]int, 5)
copy(s, slice)
s[2]=333
fmt.Println(s)
fmt.Println(slice)

}

map的定义和使用

package main

import (
"fmt"
"unsafe"
)

func main0401() {
//map定义
//var 字典名 map[键类型]值类型
//var m map[int]string = make(map[int]string, 10)
//m[1001] = "法师"
//m[8888] = "兵哥"
//
//fmt.Println(m)

//map是一个无序的的集合
m := map[int]string{1001: "法师", 8888: "兵哥", 1234: "兴臣", 3333: "孟跃平"}
//fmt.Println(m)

//k key 键 v value 值
for k, v := range m {
fmt.Println(k, v)
}
}

func main0402() {
//仅仅进行了类型声明,并没有分配内存空间,直接调用则会报错
var m0 map[string]int
//声明的同时进行了内存空间的申请
m1 := make(map[string]int)
//读取数据参数,返回参数可选,一个参数时为返回值,两个参数时第二个参数表示是否存在
//如果数据不存在则会返回数据类型的默认数据,但数据为指针类型时则返回nil,不做判断直接使用的话会panic
value,h := m1["key"]
m0 = make(map[string]int,100) //对变量进行初始化,并且预先分配存储空间大小
_,_,_ = m0,value,h
}

func main() {
//map中的key必须支持== !=运算符操作 不能是切片 map 函数
m := make(map[int]string)
m[1001] = "法师"
m[1005] = "兵哥"

//通过key判断value是否存在
if v, ok := m[1001]; ok {
fmt.Println(v)
} else {
fmt.Println("不存在key")
}

fmt.Println(len(m))
//删除map中的数据
delete(m, 1001)
fmt.Println(len(m))

fmt.Println(m)

fmt.Println(unsafe.Sizeof(m))

}

指针定义和使用

package main

import "fmt"

func main0501() {
a := 10
//取出变量a在内存的地址
//fmt.Println(&a)
var p *int = &a
//fmt.Println(p)
//fmt.Println(&a)
//通过指针间接修改变量的值
*p = 132
fmt.Println(a)

//const MAX int = 100
//fmt.Println(&MAX)//err 不可以获取常量的内存地址
}
func main() {
//定义指针 默认值为nil 指向内存地址编号为0的空间 内存地址0-255为系统占用 不允许用户读写操作
//var p *int = nil
//*p = 123 //err
//fmt.Println(*p)

//开辟数据类型大小的空间 返回值为指针类型
//new(数据类型)
var p *int
p = new(int)
*p=123
fmt.Println(*p)

}

if语句

package main

import "fmt"

func main() {
//if 表达式 {代码} 如果表达式为真 执行{}的代码
//if 表达式 {代码1} else{代码2} 如果表达式为真 执行代码1内容 如果为假 执行代码2
//if 表达式1 {代码1} else if表达式2{代码2}else{代码3} 依次判断表达式 满足条件执行

score := 0
//通过键盘获取数据 存放变量中
fmt.Scan(&score) //阻塞式请求

if score > 700 {
fmt.Println("我要上清华")
} else if score > 680 {
fmt.Println("我要上北大")
} else {
fmt.Println("我要上蓝翔")
}
}

switch语句

package main

import "fmt"

func main0701() {
//switc 表达式{case 值1:代码1 case 值2:代码2} 那个分支满足条件执行那一个

//输入月份 计算天数
day := 0
m := 0
fmt.Scan(&m)
switch m {
//如果有多个值 执行相同代码 可以使用逗号分隔
case 1, 3, 5, 7, 8, 10, 12:
day = 31
//fallthrough //执行完当前分支 继续向下执行
case 2:
day = 29
case 4, 6, 9, 11:
day = 30
default:
//默认选择
day = -1
}
fmt.Println(day)
}
func main0702() {
//pi := 3.14
////浮点型因为精度问题可能在switc中认为是同一个值
//switch pi {
//case 3.140000000000000000019999999:
// fmt.Println(pi)
//case 3.14:
// fmt.Println(pi)
//}
}
func main() {
score := 0
fmt.Scan(&score)
switch {
case score > 700:
fmt.Println("我要上清华")
case score > 680:
fmt.Println("我要上北大")
default:
fmt.Println("分数错误,程序异常")
}
}

for循环

package main

import "fmt"

func main0801() {
/*
for 表达式1;表达式2;表达式3{
代码体
}
for 表达式 {
代码体
}
for range 集合{
代码体
}
*/

//计算1-100和
sum := 0
for i := 1; i <= 100; i++ {
sum += i
}
fmt.Println(sum)
}
func main0802() {
//嵌套循环
//外层执行一次 内层执行一周
for i := 1; i <= 5; i++ {
for j := 1; j <= 5; j++ {
fmt.Println(i, j)
}
}
}

func main() {
//冒泡排序
//比较两个相邻数据元素 满足条件 交换数据位置

slice := []int{9, 1, 5, 6, 10, 8, 3, 7, 2, 4}

//外层控制行 表示执行次数
for i := 0; i < len(slice)-1; i++ {
//内层控制列 表示比较次数
for j := 0; j < len(slice)-1-i; j++ {
//比较两个相邻元素 大于号 升序排序 小于号 降序排序
if slice[j] < slice[j+1] {
//交换数据的值 = 多重赋值
slice[j], slice[j+1] = slice[j+1], slice[j]
}
}
}
fmt.Println(slice)

}