Android还没搞完又要来搞Go了,基础学习笔记,直接代码了.
ch1 第一个程序入门
package main
import (
"fmt"
"os"
)
/**
应用程序入口
必须是main包:package main
必须是main方法:func main()
文件名不一定是main.go
在hello文件夹下一样可以执行
Go中main函数不支持任何返回值
通过os.Exit来返回状态
通过os.Args获取命令行参数
*/
func main() {
fmt.Println(os.Args)
if len(os.Args)>1{
fmt.Println("Hello World",os.Args[1])
}
//os.Exit(0)
os.Exit(-1)
}
ch2
package try_test
import "testing"
/**
1. 源码⽂件以 _test 结尾: xxx_test.go
2. 测试⽅法名以 Test 开头: func TestXXX(t *testing.T) {…}
参数为t *testing.T的指针
*/
func TestFirstTry(t *testing.T) {
t.Log("My first test")
}
斐波纳挈数列
package fib
import (
"testing"
)
func TestFibList(t *testing.T) {
//var a int = 1
//var b int = 1
//var(
// a int =1
// b =1
//)
a := 1
b := 1
//fmt.Println(a,"")
t.Log(a)
for i := 0; i < 5; i++ {
//fmt.Println("",b)
t.Log(b)
tmp := a
a = b
b = tmp + a
}
//fmt.Println()
}
/**
go 中可以直接交换值
*/
func TestFibList2(t *testing.T) {
a, b := 0, 1
t.Log(b)
for i := 0; i < 5; i++ {
a, b = b, a+b
t.Log(b)
}
}
常量
package constant_test
import "testing"
/**
go 连续常量赋值及按比特位连续赋值
*/
const (
Monday = iota + 1
Tuesday
Wednesday
)
/**
常量按比特位赋值,第一位为1,第二位为1..
*/
const (
Readable = 1 << iota
Writable
Executable
)
func TestConstantTry(t *testing.T) {
t.Log(Monday, Tuesday)
}
func TestConstantTry1(t *testing.T) {
a:=1 //0001
t.Log(a&Readable==Readable,a&Writable==Writable,a&Executable==Executable)
}
ch3
类型装换
package type_test
import "testing"
/**
go的基本数据类型
隐式类型转换
*/
//定义自己的类型
type MyInt int64
func TestImplicit(t *testing.T) {
//隐式类型转换报错
var a int32 = 1
var b int64
//b = a
//t.Log(a, b)
//别名也无法进行隐式类型转换 只能使用显示类型转换 c=MyInt(b)
b = int64(a)
var c MyInt
//c = b
c = MyInt(b)
t.Log(a, b, c)
}
/**
go 指针
*/
func TestPoint(t *testing.T) {
a := 1
aPtr := &a
//go指针不能进行运算
//aPtr = aPtr + 1
t.Log(a, aPtr)
t.Logf("%T %T", a, aPtr)
}
/**
go 中初始化string时为空字符串
*/
func TestString(t *testing.T) {
//go 中空判断为nil
var s string
//判断空字符传为
if s==""{
t.Log(s)
}
t.Log("*"+s+"*")
t.Log(len(s))
}
ch4
按位操作
package operator_test
import "testing"
/**
在go中 数组长度一致可以直接==比较
*/
func TestCompareArray(t *testing.T) {
a := [...]int{1, 2, 3, 4}
b := [...]int{1, 2, 3, 5}
//c:=[...]int{1,2,3,4,5}
d := [...]int{1, 2, 3, 4}
e := [...]int{1, 3, 2, 4}
t.Log(a == b)
//长度不同无法比较
//t.Log(a==c)
t.Log(a == d)
//长度相同,内容相同,顺序不同 返回false
t.Log(a == e)
}
/**
&^ 按位清零运算符
当右侧数为1时返回0
当右侧数为0时返回左侧数
1 &^ 0 -- 1
1 &^ 1 -- 0
0 &^ 1 -- 0
0 &^ 0 -- 0
*/
const (
Readable = 1 << iota
Writable
Executable
)
func TestBitClear(t *testing.T) {
a:=7 //0111
a = a&^Readable
t.Log(a)
t.Log(a&Readable==Readable,a&Writable==Writable,a&Executable==Executable)
}
ch5
循环与条件
package condition__test
import "testing"
/**
go的条件语句中 必须是boolen值
函数支持多返回值
*/
func TestIfMultiSec(t *testing.T) {
if a := 1 == 1; a {
t.Log("1=1")
}
//多返回值处理
//if v, err := someFunc(); err == nil {
// t.Log("2==2")
//} else {
// t.Log("1==1")
//}
}
/**
switch条件
1. 条件表达式不限制为常量或者整数;
2. 单个 case 中,可以出现多个结果选项, 使⽤逗号分隔;
3. 与 C 语⾔等规则相反, Go 语⾔不需要⽤break来明确退出⼀个 case;
4. 可以不设定 switch 之后的条件表达式,在此种情况下,整个 switch 结
构与多个 if…else… 的逻辑作⽤等同
*/
func TestSwitchMultiCase(t *testing.T) {
for i := 0; i < 5; i++ {
switch i {
case 0, 2:
t.Log("EVEN")
case 1, 3:
t.Log("ODD")
default:
t.Log("It is not 0-3")
}
}
}
func TestSwitchCaseCondition(t *testing.T) {
for i := 0; i < 5; i++ {
switch {
case i%2 == 0:
t.Log("EVEN")
case i%2 == 1:
t.Log("ODD")
default:
t.Log("It is not 0-3")
}
}
}
func TestSwitchCaseCondition1(t *testing.T) {
for i := 0; i < 5; i++ {
switch {
case i&1 == 0:
t.Log("EVEN")
case i&1 == 1:
t.Log("ODD")
default:
t.Log("It is not 0-3")
}
}
}
package loop__test
import "testing"
/**
循环
*/
func TestWhileLoop(t *testing.T) {
//条件循环
n := 0;
for n < 5 {
t.Log(n)
n++
}
//无限循环
for {
t.Log(n)
}
}
ch6
数组与分片
package array_test
import "testing"
/**
var a [3]int //声明并初始化为默认零值
a[0] = 1
b := [3]int{1, 2, 3} //声明同时初始化
c := [2][2]int{{1, 2}, {3, 4}} //多维数组初始化
*/
func TestArrayInit(t *testing.T) {
var arr [4] int
arr1 := [4] int{1, 2, 3, 5}
arr3 := [...]int{1, 2, 3, 4}
arr[1] = 5
t.Log(arr[1], arr[2])
t.Log(arr1, arr3)
}
/**
遍历数组
*/
func TestArrayTravel(t *testing.T) {
arr3 := [...]int{1, 2, 3, 4}
for i := 0; i < len(arr3); i++ {
t.Log(arr3[i])
}
for idx/*索引*/, e/*元素*/ := range arr3 {
t.Log(idx, e)
}
//当不需要返回索引时,需要用下划线占位
for _,e:=range arr3{
t.Log(e)
}
}
/**
数组截取
a[开始索引(包含), 结束索引(不包含)]
a := [...]int{1, 2, 3, 4, 5}
a[1:2] //2
a[1:3] //2,3
a[1:len(a)] //2,3,4,5
a[1:] //2,3,4,5
a[:3] //1,2,3
*/
func TestArraySection(t *testing.T) {
arr3:=[...]int{1,2,3,4,5}
arr3_sec :=arr3[:3]
t.Log(arr3_sec)
//go中不支持从后向前取值
//arr3_sec1 :=arr3[:-1]
}
package slice_test
import "testing"
/**
切片,类似可变长的数组
内部结构:
ptr *Elem指针,指向一个连续空间数组
len int:元素的个数
cap int:内部数组的容量
*/
func TestSliceInit(t *testing.T) {
var s0 [] int
t.Log(len(s0), cap(s0))
s0 = append(s0, 1)
t.Log(len(s0), cap(s0))
s1 := []int{1, 2, 3, 4}
t.Log(len(s1), cap(s1))
//使用make初始化数组,第一个参数为类型,第二为长度len,第三个为容量cap
s2 := make([]int, 3, 5)
t.Log(len(s2), cap(s2))
//此时报错 index out of range [3] with length 3
//t.Log(s2[0],s2[1],s2[2],s2[3],s2[4])
t.Log(s2[0], s2[1], s2[2])
//追加一个元素,len是初始化元素的个数,cap是容量大小
s2 = append(s2, 1)
t.Log(s2[0], s2[1], s2[2], s2[3])
t.Log(len(s2), cap(s2))
}
/**
切片的扩容效果,cap增长因子是*2
cap:capacity
*/
func TestSliceGrowing(t *testing.T) {
s := []int{}
for i := 0; i < 10; i++ {
//数组append的时候需要重新赋值,cap在增长后会赋值
s = append(s, i)
t.Log(len(s), cap(s))
}
}
/**
切片共享存储结构
*/
func TestSliceShareMemory(t *testing.T) {
year := []string{"Jan", "Feb", "Mar", "Apr", "Mar", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
Q2 := year[3:6]
t.Log(Q2, len(Q2), cap(Q2))
summer := year[5:8]
t.Log(summer, len(summer), cap(summer))
summer[0] = "Unknow"
t.Log(Q2)
}
/**
数组 vs. 切⽚
1. 容量是否可伸缩
2. 是否可以进⾏⽐较
切片不能比较只能判断是否为nil
*/
func TestSliceComparing(t *testing.T) {
a := []int{1, 2, 3, 4}
b := []int{1, 2, 3, 4}
// invalid operation: a == b (slice can only be compared to nil)
//if a == b {
// t.Log("equal")
//}
}