Go 语言基础 笔记

先过一下语言基础,一些标准库和线程类的内容后续才能进行学习。

参考教程:Go 语言教程

package main
import (
"fmt"
"unsafe"
"math"
)
// 因式分解写法一般用于声明全局变量 全局变量可以声明但不使用
var (
bl bool
it int
)
// 常量的值可以是表达式的值 函数的话必须是内置函数
const (
i = "Qualcomm"
j = len(i)
k = unsafe.Sizeof(i)
)
// iota 类似C系中真正的枚举类型
const (
l = iota // 相当于等于0
m = iota // 相当于省略赋值 自动增加1
n // 直接省略 iota
o = "go" // 不使用自动增长的值 但是计数器依然增加1
p // 省略赋值 值同上 "go" 计数器增加1
q = iota // 计数器的值 计数器增加1
r // 省略赋值
)
type Book struct {
name string
price float64
out bool
}
// 结构体也是一个对象
type Circle struct {
redius float64
}
func main() {
fmt.Println("Hello, world!")
// 变量声明
var a = 15
var b float32 = 3.1415926
c := "Go"
fmt.Println(a, b, c)
// 不带格式的声明只能放在函数体内
d, e, f := "D", 'E', 'F'
fmt.Println(d, e, f)
// 输出全局变量
fmt.Println(bl)
fmt.Println(&it)
// 基本类型数字、字符串属于值类型
var g = 100
// 相互赋值会将值进行拷贝
var h = g
fmt.Println(g, h)
// 所以内存空间是不同的
fmt.Println(&g, &h)
// 交换两个变量的值 两个变量的类型需要一致
fmt.Println(e, f)
e, f = f, e
fmt.Println(e, f)
// 常量声明 常量可以声明但不使用
const PI, PATH = 3.14, "/usr/bin/go"
fmt.Println("The path of go bin is", PATH)
fmt.Println(i, j, k)
// iota 枚举
fmt.Println(l, m, n, o, p, q, r)
// 算数运算
fmt.Println(5 + 2)
fmt.Println(5 - 2)
fmt.Println(5 * 2)
fmt.Println(5 / 2) // 整数相除结果取整
fmt.Println(5.0 / 3) // 浮点数相除结果还是浮点 默认精确到十六位
fmt.Println(5 % 2)
// 关系运算
fmt.Println(1 == 2)
fmt.Println(1 != 2)
fmt.Println(1 > 2)
fmt.Println(1 < 2)
fmt.Println(1 >= 2)
fmt.Println(1 <= 2)
// 逻辑运算
fmt.Println(1 < 2 && 2 > 3)
fmt.Println(1 < 2 || 2 > 3)
fmt.Println(!(1 < 2))
// 位运算
// &:按位与 1&1=1 其余为 0
// |:按位或 0|0=0 其余为 1
// ^:按位异或 与1异或为相反值 与0异或为自身
// <<:左移运算 二进制数往左移位 高位丢弃 低位补零 相当于乘以2的N次方
// >>:右移运算 二进制数往右移位 低位丢弃 高位补零 相当于除以2的N次方
s := 60 // 0011 1100
t := 13 // 0000 1101
/*
s: 0011 1100
t: 0000 1101
&: 0000 1100 => 12
*/
fmt.Println(s & t)
/*
s: 0011 1100
t: 0000 1101
|: 0011 1101 => 61
*/
fmt.Println(s | t)
/*
s: 0011 1100
t: 0000 1101
^: 0011 0001 => 49
*/
fmt.Println(s ^ t)
/*
s: 0011 1100
<<2: 1111 0000 => 240
*/
fmt.Println(s << 2)
/*
s: 0011 1100
>>2: 0000 1111 => 15
*/
fmt.Println(s >> 2)
// 其它运算
ptr := &s
fmt.Println(&s)
fmt.Println(ptr)
fmt.Println(s)
fmt.Println(*ptr)
// if 语句
if s >= 80 {
fmt.Println("Great!")
} else if s >= 60 {
fmt.Println("Good!")
} else {
fmt.Println("Not good!")
}
// switch 语句
grade := "B"
point := 90
switch point {
case 90:
grade = "A"
case 80:
grade = "B"
case 70, 60, 50:
grade = "C"
default:
grade = "D"
}
switch {
case grade == "A":
fmt.Println("Great!")
case grade == "B":
fmt.Println("Good!")
case grade == "C":
fmt.Println("Not bad!")
case grade == "D":
fmt.Println("Bad!")
default:
fmt.Println("Bads!")
}
fmt.Printf("Your grade is %s\n", grade)
// type-switch
var intf interface{}
switch tp := intf.(type) {
case nil:
fmt.Printf("Type of tp is %T\n", tp)
case int:
fmt.Printf("Type of tp is int\n")
case float32:
fmt.Printf("Type of tp is float32\n")
case func(int) float32:
fmt.Printf("Type of tp is func(int) float32\n")
case bool, string:
fmt.Printf("Type of tp is bool or string\n")
default:
fmt.Printf("Type of tp is unknown\n")
}
// for 语句
for i := 0; i < 10; i++ {
fmt.Println(i)
}
numlist := [6]int{1, 2, 3, 5}
for k, v := range numlist {
fmt.Printf("Index %d of numlist is %d\n", k, v)
}
// 类似 while 语句
index := 5
for index < 10 {
fmt.Println(index)
index++
}
for i := 0; i <= 10; i++ {
if i % 2 == 0 {
fmt.Println(i)
//continue
}
if i == 8 {
break
}
}
// 函数调用
fmt.Println(swap(12, 23))
// 值传递 不会更改变量本身的值
num1, num2 := 12, 23
fmt.Printf("Before swap: num1 = %d, num2 = %d\n", num1, num2)
fmt.Println(swap(num1, num2))
fmt.Printf("After swap: num1 = %d, num2 = %d\n", num1, num2)
// 引用传递 会更改变量本身的值
fmt.Printf("Before swap2: num1 = %d, num2 = %d\n", num1, num2)
swap2(&num1, &num2)
fmt.Printf("After swap2: num1 = %d, num2 = %d\n", num1, num2)
// 匿名函数作变量类型 跟JS中一样
sqrtFunc := func(x float64) float64 {
return math.Sqrt(x)
}
fmt.Println(sqrtFunc(9))
// 函数闭包
// 闭包: 闭包使得函数执行完后不会被释放,函数内部的局部变量依然存在并可以进行更新.
iadd := sum(2, 3)
fmt.Println(iadd())
fmt.Println(iadd())
fmt.Println(iadd())
fmt.Println(iadd())
// 方法
var cl Circle
cl.redius = 10.0
// 调用cl这个实例的方法
fmt.Println("Area of Circle(cl) is", cl.getArea())
// 数组
var arr1[3] int
var arr2 = [3] float64 {0.1, 0.2, 0.3}
var arr3 = [] int {4, 5, 6}
fmt.Println(arr1)
fmt.Println(arr2)
fmt.Println(arr3)
var arr4[10] int
for i := 0; i < 10; i++ {
arr4[i] = i
}
fmt.Println(arr4)
for i := 0; i < 10; i++ {
fmt.Println(arr4[i])
}
var arr5[2][3] int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
arr5[i][i] = j
}
}
fmt.Println(arr5)
// 数组做参数
fmt.Println(sumArr(arr3))
// 指针
var ptr1 *int = &a
fmt.Printf("Pointer of a is %x\n", ptr1)
fmt.Printf("Value of point pt1 is %d\n", *ptr1)
// 指针数组
numlist2 := [] int {12, 34, 56}
var ptr3 [3] *int
for i := 0; i < 3; i++ {
fmt.Println(i)
ptr3[i] = &numlist2[i]
}
for i := 0; i < len(numlist2); i++ {
fmt.Printf("Pointer address of %d is %x\n", *ptr3[i], ptr3[i])
}
// 指向指针的指针
var ptr2 **int = &ptr1
fmt.Printf("Address of ptr2 is %x\n", ptr2)
fmt.Printf("Address of *ptr2 is %x\n", *ptr2)
fmt.Printf("Value of ptr1 is %d\n", **ptr2)
// 指针做参数 参考前面引用传递
// 结构体
bk1 := Book{"English", 23.40, false}
fmt.Printf("Book name: %s\n", bk1.name)
// 结构体做参数
bkinfo(bk1)
// 结构体指针
bkname(&bk1)
}
// 交换两个数字 值传递
func swap(x, y int) (int, int) {
return y, x
}
// 交换两个数字 引用传递
func swap2(x, y *int) {
*x, *y = *y, *x
}
// 带参数闭包 求和
func sum(a, b int) func() (int, int) {
i := 0
return func() (int, int) {
i += 1
return i, a + b
}
}
// 该方法属于 Circle 这个对象
func (c Circle) getArea() float64 {
return 3.14 * c.redius * c.redius
}
// 数组做形参
func sumArr(arr []int) int {
sum := 0
for i := 0; i < len(arr); i++ {
sum += arr[i]
}
return sum
}
// 结构体做参数
func bkinfo(bk Book) {
fmt.Printf("Book name: %s\n", bk.name)
}
// 结构体指针做参数
func bkname(bk *Book) {
fmt.Printf("Book name: %s\n", bk.name)
}