go语言基础学习笔记

目录

  • GOROOT:Go的根目录

  • GOPATH:用户工作区,源码必须放这里

  • 系统PATH下增加$GOROOT/bin:可以直接执行的命令

  • src源码

  • pkg go install命令 归档文件 .a

  • bin 可执行文件

编译

  • 直接执行
go run hello_world.go
  • 编译
go build hello_world.go

应用程序入口

  • package 必须是main(目录不强制)
  • func 必须是main
  • 文件名不强制main.go
package main
import "fmt"
func main()  {
	fmt.Println("hello world")
}

退出

func main 不支持返回值
os.Exit 立即中止,返回状态

命令行参数

func main 不支持传入参数
os.Args获取命令行参数

func main()  {
	if len(os.Args) > 1{
		fmt.Println("Hello ",os.Args[1]) //获取命令行参数
	}
	os.Exit(-1) //异常退出
}

测试程序

  • 源码文件_test结尾,xxx_test.go
  • 测试方法Test开头 func TestXX(t *testing.T)
first_test.go

package test
import "testing"
func TestFirst(t *testing.T){
	t.Log("test");
}

变量

//全局
var c  int
func TestFirst(t *testing.T){
	//变量声明
	var a int = 1
	var b int = 1

	//简写
	var (
		a int = 1
		b int = 1
	)

	//类型推断
	a := 1
	b := 1
	fmt.Println(a)
	for i:=0; i<5; i++{
		fmt.Println(b)
		tmp := a
		a = b
		b = tmp + a
	}
变量交换
a,b = b,a

常量

连续常量
//连续常量
const(
	Mon = 1 + iota
	Thus
	Web
)

//一般常量
const(
	GOOGLE =  "go"
	BAIDU = "bd"
)

//位运算常量
const(
	READABLE = 1 << iota  //1的二进制 1
	WRITEABLE //左移一位 10
	EXECABLE //左移一位 100
)

func TestConst(t *testing.T){
	t.Log(Mon,Thus,Web)
	t.Log(GOOGLE,BAIDU)
	t.Log(READABLE,WRITEABLE,EXECABLE)
}


数据类型

bool
string
//标注位数可以忽略平台差别导致的问题
//int uint在32位机器是32位  64位机器是64位
int int8 int16 int32 int64
unit unit8 unit16 uint64 uintptr
byte //uint8的别名
rune //int32别名 unicode编码值
float32 float64
complex64 complex128

类型转换

  • 不支持隐式转换(包括原类型和别名类型) type MyInt int64

类型预定义值

  • math.MaxInt64
  • math.MaxFloat64
  • math.MaxUint64

指针类型

  • 不支持指针运算
  • string是值类型,默认值是空字符串
func TestType(t *testing.T){
	var a int = 1
	var b int64
	b = int64(a) //显式转换
	t.Log(b)
}

func TestPtr(t *testing.T){
	a := 1
	aPtr := &a
	t.Log(aPtr) //指针地址 0xc00000a298
	t.Logf("%T %T",a,aPtr) // %T格式化符号 (int *int)
}

默认值

  • *int ------- nil
  • int ------- 0
  • float32 ------- 0
  • bool ------- false

比较运算

  • 数组比较条件(编译错误):
  1. 相同维
  2. 相同个数
  • 每个元素都相等才是相等

循环

  • 只支持for,不需要括号
//一般循环
func TestLoop(t *testing.T){
	n := 0
	for n <= 5{
		t.Log(n)
		n++
	}
}

//无限循环
func TestRunLoop(t *testing.T){
	n := 0
	for{
		n++
		t.Log(n)
	}
}

判断

  • 不需要括号
  • condition结果布尔
  • 支持变量赋值
func TestCondition(t *testing.T){
	// 变量表达式;条件
	if v,err := someFun(2); err == nil{
		t.Log("正常",v)
	}else{
		t.Log("错误",err)
	}
}

func someFun(b int) (result int,err error){
	err = nil
	if b == 1 {
		result = b
	}else{
		err = errors.New("Test Error")
	}
	return
}

数组

声明
  • var a [3]int //声明并初始化为默认零值
  • a[0] = 1
  • b := [3]int{1, 2, 3} //声明同时初始化
  • c := [2][2]int{{1, 2}, {3, 4}} //多维数组初始化
遍历
func TestTravelArray(t *testing.T) {
    a := [...]int{1, 2, 3, 4, 5} //不指定元素个数
    for idx/*索引*/, elem/*元素*/ := range a {
        fmt.Println(idx, elem)
    }
}
截取
  • a[开始索引(包含), 结束索引(不包含)]
a[1:2] //2

切片

声明
  • var s0 []int
  • s0 = append(s0, 1)
  • s := []int{}
  • s1 := []int{1, 2, 3}
  • s2 := make([]int, 2, 4)
    /*[]type, len, cap
    其中len个元素会被初始化为默认零值,未初始化元素不可以访问
    */

-数组 vs 切片:伸缩 比较

map

声明
  • m := map[string]int{"one": 1, "two": 2, "three": 3}
  • m1 := map[string]int{}
  • m1["one"] = 1
  • m2 := make(map[string]int, 10 /Initial Capacity/)
元素访问
//m["four"]返回两个值,存在的话第二个是bool的true
if v, ok := m["four"]; ok {
    t.Log("four", v)
} else {
    t.Log("Not existing")
}
遍历foreach
m := map[string]int{"one": 1, "two": 2, "three": 3}
for k, v := range m {
    t.Log(k, v)
}

map实现工厂模式

  • Map 的 value 可以是⼀个⽅法
  • 与 Go 的 Dock type 接⼝⽅式⼀起,可以⽅便的实现单⼀⽅法对象的⼯⼚模式
func TestMapWithFunValue(t *testing.T) { 
 	m := map[int]func(op int) int{} 
 	m[1] = func(op int) int { return op } 
 	m[2] = func(op int) int { return op * op } 
 	m[3] = func(op int) int { return op * op * op } 
 	t.Log(m[1](2), m[2](2), m[3](2)) //以2为输入参数
 } 

set的实现

基本定义
  1. 元素的唯⼀性
  2. 基本操作
    1. 添加元素
    1. 判断元素是否存在
    1. 删除元素
    1. 元素个数
func TestMapForSet(t *testing.T) { 
 	mySet := map[int]bool{} 
 	
 	//添加元素
 	mySet[1] = true  
 	n := 3 
 	
 	//判断元素是否存在
 	if mySet[n] { 
 		t.Logf("%d is existing", n) 
 	} else { 
 		t.Logf("%d is not existing", n) 
 	} 
 	
 	//判断元素长度
 	t.Log(len(mySet))
 	
 	//删除元素
 	delete(mySet, 1) 
} 

字符串

  1. string 是数据类型,不是引⽤或指针类型
  2. string 是只读的 byte slice, len 函数可以它所包含的 byte 数(其实就是类似字节数组)
  3. string 的 byte 数组可以存放任何数据(可见字符 不可见字符)
func TestString(t *testing.T) {
	var s string
	t.Log(s) //初始化为默认零值“”
	
	s = "hello"
	t.Log(len(s))  //长度 5 
	
	s[1] = '3' //string是不可变的byte slice,这样写 编译错误

	s = "\xE4\xBA\xFF" //可以存储任何二进制数据
	t.Log(s) //严
	t.Log(len(s)) //长度 3
	
	//byte & unicode区别
	s = "中"
	t.Log(len(s)) //是byte数
	c := []rune(s) //能取出字符串里面的unicode(rune切片)
	t.Log(len(c)) //长度1
	
	
	//	t.Log("rune size:", unsafe.Sizeof(c[0]))
	t.Logf("中 unicode %x", c[0])
	t.Logf("中 UTF8 %x", s)
}
func TestStringToRune(t *testing.T) {
	s := "*"
	for _, c := range s {
		t.Logf("%[1]c %[1]d", c) //汉字 编码
	}
}
  1. Unicode 是⼀种字符集(code point 相当于标准)
  2. UTF8 是 unicode 的存储实现 (转换为字节序列的规则)
字符
Unicode 0x4E2D
UTF-8 0xE4B8AD
string/[]byte [0xE4,0xB8,0xAD]
字符串操作函数
//用逗号分隔成切片
func TestStringFn(t *testing.T) {
	s := "A,B,C"
	parts := strings.Split(s, ",")
	for _, part := range parts {
		t.Log(part)
	}
	
    //字符串连接
	t.Log(strings.Join(parts, "-"))
}

func TestConv(t *testing.T) {
    //整数转字符串
	s := strconv.Itoa(10) 
	t.Log("str" + s)
	
	//字符串转整形
	if i, err := strconv.Atoi("10"); err == nil {
		t.Log(10 + i)
	}
}

函数:一等公民

  1. 可以有多个返回值
  2. 所有参数都是值传递: slice, map, channel 会有传引⽤的错觉(其实也是传值,因为slice对应的数组,整个数据结构有指针指向同一数组)
  3. 函数可以作为变量的值
  4. 函数可以作为参数和返回值
  • 多返回值
func returnMultiValues() (int, int) {
	return rand.Intn(10), rand.Intn(20)
}

//调用时忽略一个返回值
a, _ := returnMultiValues() 
  • 装饰器模式(计时函数)
func timeSpent(inner func(op int) int) func(op int) int {
	return func(n int) int {
		start := time.Now()
		ret := inner(n)
		fmt.Println("time spent:", time.Since(start).Seconds())
		return ret
	}
}

func slowFun(op int) int {
	time.Sleep(time.Second * 1)
	return op
}

//调用
tsSF := timeSpent(slowFun)
t.Log(tsSF(10))

可变参数

//参数会转化成数组
func sum(ops ...int) int {
    s := 0
    for _, op := range ops {
        s += op
    }
    return s
}

defer 延迟最后执行

  • 类似 try .. finally,就上panic的异常中断也会继续执行
func TestDefer(t *testing.T) {
    defer func() {
        t.Log("Clear resources")
    }()
    t.Log("Started")
    panic("Fatal error”) //defer仍会执⾏
}
上一篇:Window 安装Hive


下一篇:hive3.1.1 hive-site.xml