人生苦短,let’s go
本人从B站看视频学习go,具体的学习网站可以参考链接为:李文周的博客
一下是本人参考学习的一些练习。
截图是本人最近学习的基础学习demo
下面是具体的代码
基础部分:
package main
import (
"fmt"
"reflect"
)
var x, y int
var ( // 这种因式分解关键字的写法一般用于声明全局变量
a int
b bool
)
const (
Unknown = 0
Female = 1
Male = 2
)
var c, d int = 1, 2
var e, f = 123, "hello"
func main() {
fmt.Println("人生苦短," + "let's go")
fmt.Println("单行注释 // 多行注释/**/")
fmt.Println("标识符可以是以下划线开头或者字母开头,不能以数字开头")
fmt.Println("go 语言数据类型以及默认值")
var i int
var f float64
var s string
fmt.Println("%v %v %v %q\n", i, f, b, s)
fmt.Println("%s,%s", reflect.TypeOf(d), reflect.TypeOf(s))
//:= 左侧如果没有声明新的变量,就产生编译错误
//这种不带声明格式的只能在函数体中出现
//局部变量,声明必须用,全局变量可以只声明不去用 declared and not used
g, h := 123, "hello"
fmt.Println(x, y, a, b, c, d, e, f, g, h)
//空白标识符 _ 也被用于抛弃值,只获取函数返回值的后两个
_, aa, bb := number()
fmt.Println("%s,%s", aa, bb)
fmt.Println(Unknown, Female, Male)
aaa, bbb := swap("Google", "Runoob")
fmt.Println(aaa, bbb)
}
//一个可以返回多个值的函数
func number() (int, int, string) {
a, b, c := 1, 2, "go"
return a, b, c
}
//数据交换
func swap(x, y string) (string, string) {
return y, x
}
/* 函数返回两个数的最大值 */
func max(num1, num2 int) int {
/* 定义局部变量 */
var result int
if (num1 > num2) {
result = num1
} else {
result = num2
}
return result
}
数组切片部分
package main
import "fmt"
/*
数组是同一种数据类型元素的集合。 在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小不可变化。 基本语法:
// 定义一个长度为3元素类型为int的数组a
var a [3]int
*/
func modifyArray(x [3]int) {
x[0] = 100
}
func main() {
//编译器根据初始值的个数自行推断数组的长度
//%T 打印当前对象的类型
// var testArray [3]int ////数组会初始化为int类型的零值
// var numArray = [...]int{1, 2}
// var cityArray = [...]string{"北京", "上海", "深圳"}
// fmt.Println(testArray) //[0 0 0]
// fmt.Println(numArray) //[1 2]
// fmt.Printf("type of numArray:%T\n", numArray) //type of numArray:[2]int
// fmt.Println(cityArray) //[北京 上海 深圳]
// fmt.Printf("type of cityArray:%T\n", cityArray) //type of cityArray:[3]string
//指定索引值的方式来初始化数组
array :=[...]int{1:1,4:8} //打印出索引为1的数字为1,索引为4的数字为8,其他的初始化为int类型的零值
const length=len(array)
i :=0
for i< length {
fmt.Println(array[i])
i++
}
fmt.Println(i)
//for range遍历
for index , value :=range array {
fmt.Println(index, value)
}
//二维数组的定义
m := [3][2]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
}
fmt.Println(m) //[[北京 上海] [广州 深圳] [成都 重庆]]
fmt.Println(m[2][0]) //支持索引取值:成都
//遍历
for _, v1 := range m {
for _, v2 := range v1 {
fmt.Printf("%s\t", v2)
}
fmt.Println()
}
//数组是值类型,赋值和传参会复制整个数组。因此改变副本的值,不会改变本身的值
n := [3]int{10, 20, 30}
modifyArray(n) //在modify中修改的是a的副本x
fmt.Println(n) //[10 20 30]
}
package main
import "fmt"
func main() {
// 声明切片类型
// var a []string //声明一个字符串切片
// var b = []int{} //声明一个整型切片并初始化
// var c = []bool{false, true} //声明一个布尔切片并初始化
// fmt.Println(a) //[]
// fmt.Println(b) //[]
// fmt.Println(c) //[false true]
// fmt.Println(a == nil) //true
// fmt.Println(b == nil) //false
// fmt.Println(c == nil) //false
// a := [5]int{55, 56, 57, 58, 59}
// b := a[1:4] //基于数组a创建切片,包括元素a[1],a[2],a[3]
// fmt.Println(b) //[56 57 58]
// fmt.Printf("type of b:%T\n", b) //type of b:[]int
//切片再切片
// a := [...]string{"北京", "上海", "广州", "深圳", "成都", "重庆"}
// fmt.Printf("a:%v type:%T len:%d cap:%d\n", a, a, len(a), cap(a))
// b := a[1:3]
// fmt.Printf("b:%v type:%T len:%d cap:%d\n", b, b, len(b), cap(b))
// c := b[2:5]
// fmt.Printf("c:%v type:%T len:%d cap:%d\n", c, c, len(c), cap(c))
//下面代码中a的内部存储空间已经分配了10个,但实际上只用了2个。 容量并不会影响当前元素的个数,所以len(a)返回2,cap(a)则返回该切片的容量
// a := make([]int, 2, 10)
// fmt.Println(a) //[0 0]
// fmt.Println(len(a)) //2
// fmt.Println(cap(a)) //10
// a := [8]int{0, 1, 2, 3, 4, 5, 6, 7}
// fmt.Println(a[:5])//
// fmt.Println(a[:3])
// fmt.Println(a[3:5])
// fmt.Println(a[5:])
//[0 1 2 3 4]
// [0 1 2]
// [3 4]
// [5 6 7]
//切片的遍历方式和数组是一致的,支持索引遍历和for range遍历
// s := []int{1, 3, 5}
//append()方法为切片添加元素
// Go语言的内建函数append()可以为切片动态添加元素,每个切片会指向一个底层数组,这个数组的容量够用就添加新增元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。
// “扩容”操作往往发生在append()函数调用时,所以我们通常都需要用原变量接收append函数的返回值。
// s=append(s,4)
// for index,val := range s {
// fmt.Println(index, val)
// }
// var citySlice []string
// // 追加一个元素
// citySlice = append(citySlice, "北京")
// // 追加多个元素
// citySlice = append(citySlice, "上海", "广州", "深圳")
// // 追加切片
// a := []string{"成都", "重庆"}
// citySlice = append(citySlice, a...)
// fmt.Println(cap(citySlice)) //[北京 上海 广州 深圳 成都 重庆]
//切片扩容
// 首先判断,如果新申请容量(cap)大于2倍的旧容量(old.cap),最终容量(newcap)就是新申请的容量(cap)。
// 否则判断,如果旧切片的长度小于1024,则最终容量(newcap)就是旧容量(old.cap)的两倍,即(newcap=doublecap),
// 否则判断,如果旧切片长度大于等于1024,则最终容量(newcap)从旧容量(old.cap)开始循环增加原来的1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最终容量(newcap)大于等于新申请的容量(cap),即(newcap >= cap)
// 如果最终容量(cap)计算值溢出,则最终容量(cap)就是新申请容量(cap)。
//由于切片是引用类型,所以a和b其实都指向了同一块内存地址。修改b的同时a的值也会发生变化
// a := []int{1, 2, 3, 4, 5}
// b := a
// fmt.Println(a) //[1 2 3 4 5]
// fmt.Println(b) //[1 2 3 4 5]
// b[0] = 1000
// fmt.Println(a) //[1000 2 3 4 5]
// fmt.Println(b) //[1000 2 3 4 5]
//go 中的copy copy(destSlice, srcSlice []T) srcSlice: 数据来源切片 destSlice: 目标切片
//a := []int{1, 2, 3, 4, 5}
//make([]T, size, cap) T:切片的元素类型 size:切片中元素的数量 cap:切片的容量
// c := make([]int, 5, 5)
// fmt.Println(c) [0 0 0 0 0]
// a := []int{1, 2, 3, 4, 5}
// copy(c,a)
// fmt.Println(c) [1 2 3 4 5]
// c[0]=1000
// fmt.Println(c) [1000 2 3 4 5]
// fmt.Println(a) [1 2 3 4 5]
// 从切片中删除元素
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
// 要删除索引为4的元素
a = append(a[:4], a[5:]...)
fmt.Println(a) //[30 31 33 34 35 36 37]
//从切片a中删除索引为index的元素,操作方法是a = append(a[:index], a[index+1:]...)
}
以上仅本人学习总结,不喜欢勿喷