用于以后复习GO,GO零基础应该看不懂
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net"
"os"
"reflect"
"runtime"
"strconv"
"sync"
"time"
)
//import . "fmt"//导入所有包
//import otherName "fmt"//取别名
//import _ "fmt"//忽略此包
//变量、输入、打印
func base1() {
//一个文件夹只能有一个main
a := 78 //临时变量
a += 800
var b, c int //初始值为0
var d int = 100
e, f, g := 2, 5, 8
f, g = g, f
const h string = "this_is_const_h"
var (
i int = 45
j string = "this_is_j"
)
const (
//iota在const自动自动增长,如果是同一行,值都一样
k = iota //0
m = iota //1
)
{
const (
//iota在const自动自动增长,如果是同一行,值都一样
k = iota //0
m //1
n //2
o //3
p //4
)
}
o := 3 + 4i
/*
类型:bool(true,false)、byte、rune(4,储存unicode码,可储存中文字符)、
int、uint、complex64/128(复数类型)、uintptr(4,指针类型)
*/
n := '中'
fmt.Printf("a=%d,c=%d\n\a", a, c)
//%T操作变量所属类型
// %v自动匹配格式输出
fmt.Println(a, "556", b, c, d, e, f, g, h[1:3], i, j, n, o)
fmt.Println(real(o), imag(o)) //复数的实部虚部
var sa string
fmt.Scanf("%s", &sa)
fmt.Println(sa)
fmt.Scan(&sa)
fmt.Println(sa)
fmt.Printf("%d", int('a')) //类型转换
//bool不可以转int
type newName int
}
//多返回值,匿名返回
func f3() (int, int, int) {
return 1, 2, 5
}
//泛型
func f2[T any](a ...T) (result int) {
//两种返回
result = 7
return 2
}
//e为不定参数
func f1(a, b int, c, d string, e ...int) int {
f2[int](e...) //e里的所有值都传入f2
f2(e[4:]...)
return 1
}
//条件、循环、函数
func base2() {
var a = 10
//if语句写法1
if a == 12 {
} else {
}
//if语句写法2
//第一个为赋值,第二个为条件
if a = 10; a == 10 {
}
//第一个初始化,第二个条件
switch a = 4; a {
case 1: //默认不写break
fallthrough //执行下面的
case 2:
fallthrough //执行下面的
case 3, 4, 5:
default:
}
//for1
for i := 0; i < 100; i++ {
}
//for2
str := "hello"
for i, s := range str {
fmt.Printf("【i=%v,s=%v】", i, s)
}
//for3
for i := range str {
fmt.Printf("【i=%v,s=%v】", i, str[i])
}
//for3默认为true
for {
break
}
goto laber1
laber1:
//函数类型
type TF1 func() (int, int, int)
var tf TF1
tf = f3
tf()
tf()
tf()
tf() //tf内的变量依然存在,不会被释放(可用来做自增)
func() (int, int) { return 1, 2 }() //匿名函数并调用
var ff2 = func() {}
ff2()
defer fmt.Println("在函数结束前调用defer") //多个defer,先进后出,堆
fmt.Println("序号1")
}
type char byte
func (c char) disp() { //绑定函数
fmt.Printf("%c", c)
}
//接口
type api interface {
//只有声明,没有实现
apiFunc()
}
type mint int
//接口绑定,只针对自定义数据类型
func (c char) apiFunc() {
fmt.Print(c)
}
func (i mint) apiFunc() {
fmt.Print(i)
}
type person struct {
Name string
age int
}
//多重继承,嵌套多个结构体
type person2 struct {
person //匿名继承
int
}
func (p *person) GetAge() int { return p.age }
func (p *person) SetAge(age int) { p.age = age }
// NewPerson 构造函数
func NewPerson(name string) *person { return &person{Name: name} }
//数组、字典、结构体、类
func base3() {
var a = [40]int{8, 5, 9, 6, 15: -1, 20: -89} //部分初始化:下标:值
b := [20][30]int{
{1, 2, 5},
5: {1, 2, 4, 8: -55},
}
fmt.Println(a)
fmt.Println(b)
//var b[n]int//不能用n
for i := range a {
a[i] = i
}
c := [5]int{1, 2, 3}
d := [5]int{1, 0, 3}
fmt.Println(c == d, c != d) //false true
//随机数
rand.Seed(time.Now().UnixNano()) //设置种子
fmt.Println(rand.Intn(100))
var e = []int{1, 2, 3, 4, 5}
f := []int{1, 2, 3, 4, 5}
g := e[1:3:4] //内容[1,3)容量3
h := make([]int, 5, 10) //len=5,cap=10,5个0
fmt.Println(e, f, g)
fmt.Println(len(g), cap(g)) //2 3
h = append(h, 4)
fmt.Println(h) //[0 0 0 0 0 4]
copy(g, h) //h->g
m1 := map[byte]string{
'a': "hello",
'b': "world",
}
m1['c'] = "C++"
fmt.Println(m1)
for key, val := range m1 {
fmt.Println(key, val)
}
val, ok := m1['d'] //是否存在键
fmt.Println(val, ok)
delete(m1, 'c')
//首字母大写结构体(类)是public,小写private,属性方法也一样
type ST1 struct {
v1 string
v2 int
next *ST1
}
var st1 = ST1{"444", 8, new(ST1)}
var st2 = &ST1{v1: "444", v2: 8}
fmt.Println(st1, st2, st1.v2, st2.v1, (*st2).v1) //st2.v1与(*st2).v1等价
fmt.Println(st1 == *st2, st1 != *st2) //false true
var st3 ST1
st3 = st1
fmt.Println(st3)
type ST2 struct {
v2 int
ST1 //继承ST1中的属性
v3 int
}
st21 := ST2{500, ST1{"sss", 44, new(ST1)}, 40}
st21.v1 = "hello struck"
st21.ST1 = ST1{"hej", 78, new(ST1)}
st21.ST1.v2 = 45
fmt.Printf("%+v", st21)
ch1 := char('a')
ch1.disp() //方法绑定
cf := ch1.disp //方法值
cf()
cf1 := (*char).disp //方法表达式1
cf1(&ch1)
cf2 := char.disp //方法表达式2
cf2(ch1)
var aa [4]interface{}
aa[1] = 1234
aa[2] = "asdfg"
aa[3] = [5]int{1, 2, 5, 85}
fmt.Println("\n\naa>>>", aa)
var bb int
bb = aa[1].(int) //断言,aa[]是空接口类型,不能直接赋值给bb,需要断言
fmt.Println(bb)
{
a := NewPerson("hello")
a.SetAge(58)
var b person2
b.person = *a
b.int = 10 //直接访问匿名字段
fmt.Println(a)
fmt.Println(b)
}
}
type Monster struct {
//序列化后Name->monster_name
Name string `json:"monster_name"`
Age int `json:"monster_age"`
}
func (v Monster) print() {
fmt.Println("MonsterPrint-->\n", "Name>>>", v.Name, "\nAge>>>", v.Age)
}
type myAny interface{}
//func anys2T[T any]()
func base4() {
//文件操作File的方法(位于os包中)
//Read、ReadAt、Write、WriteString、WriteAt、Seek、Sync、Close
fileName := "E:\\编程测试文件\\1005.txt"
//fileOpenError := "file open error"
readByBufio := func(fileName string) string {
f, e := os.Open(fileName)
fmt.Println(f, e)
if e != nil {
fmt.Println("file open error")
return ""
}
//带缓冲的读取(4096),适用于大文件读取
reader := bufio.NewReader(f)
fmt.Println(reader)
i := 0
var text string = ""
for {
//读取,读到换行结束
s, e := reader.ReadString('\n')
//读到末尾
if e == io.EOF {
break
}
text += s
fmt.Print("L", i, ">>>", s)
i++
}
err := f.Close()
if err != nil {
return ""
}
return text
}
readByBufio(fileName)
//一次性读取,适用于小文件读取
//text为[]byte类型
readByIoutil := func(fileName string) string {
f, e := os.Open(fileName)
fmt.Println(f, e)
if e != nil {
fmt.Println("file open error")
return ""
}
text, e := ioutil.ReadFile(fileName) //无需close
if e != nil {
fmt.Println("file open error")
return ""
} else {
fmt.Println(text)
fmt.Println(string(text))
}
e = f.Close()
return string(text)
}
readByIoutil(fileName)
fileWriteByBufio := func(fileName string, flag int, text []string) {
//文件读写
//路径,模式,权限
f, e := os.OpenFile(fileName, flag, 4)
if e != nil {
fmt.Println("file open error")
} else {
w := bufio.NewWriter(f)
//写入缓存
for i, t := range text {
//写入缓存
w.WriteString(t)
i++
}
//写入磁盘
//w.Flush()
}
//带缓存的write
e = f.Close()
}
fileWriteByBufio(fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, []string{"hello1\n", "hello2\n"})
readByBufio(fileName)
pathExists := func(fileName string) (bool, error) {
//e为nil时存在,为os.IsNotExist(e)为true时不存在,其他类型不确定
_, e := os.Stat(fileName)
if e == nil {
return true, nil
}
if os.IsExist(e) == true {
return false, nil
}
return false, e
}
pathExists(fileName)
{
//获取命令行参数os.Args
fmt.Println(os.Args)
var (
user string
pwd string
host string
port int
)
//自动解析参数值 mysql -u root -pwd 123 ...
flag.StringVar(&user, "u", "", "用户名默认为空")
flag.StringVar(&pwd, "pwd", "", "密码默认为空")
flag.StringVar(&host, "h", "127.0.0.1", "主机名默认为127.0.0.1")
flag.IntVar(&port, "port", 3306, "用户名默认为3306")
flag.Parse() //开始转换
}
{
//myAny=interface{}
//return->[]string|[][]byte
toJson := func(maps []myAny) [][]byte { //411
var datat [][]byte
// 序列化map
for _, m := range maps {
data, _ := json.Marshal(m)
datat = append(datat, data)
}
return datat
}
a := map[string]myAny{"name": "namemmmm", "age": 888}
s := person{"nameppp", 45} //private类型不参加序列化
m := Monster{"nameMonster", 777}
jsonbyt := toJson([]myAny{s, a, m})
fmt.Println("jsonbyt>>>")
for _, i := range jsonbyt {
fmt.Println(string(i))
}
fmt.Println((jsonbyt))
fromJson := func(js [][]byte) []myAny {
var T []myAny
for _, i := range js {
var t myAny
json.Unmarshal(i, &t)
T = append(T, t)
}
return T
}
fmt.Println("fromJson>>>")
result := fromJson(jsonbyt)
fmt.Println(result)
aa := toJson([]myAny{s, s, s})
bb := fromJson(aa)
fmt.Println("fromJson>>>bb>>")
fmt.Println(bb)
//p := bb[0].(person)
//fmt.Println(p)
rVal := reflect.ValueOf(myAny(m)) //any->reflect.ValueOf
rTyp := reflect.TypeOf(myAny(m))
fmt.Println("rVal>>>", rVal, rTyp)
iVal := rVal.Interface() //reflect.ValueOf->any
v := iVal.(Monster) //any->struct
fmt.Println(v, iVal.(Monster).Name)
{
var a int64 = 4
rVal := reflect.ValueOf(myAny(a)) //any->reflect.ValueOf
//rVal.SetInt(88) //改变rVal//error
rpVal := reflect.ValueOf(myAny(&a)) //any->reflect.ValueOf
rpVal.Elem().SetInt(99) //改变a
fmt.Println(rVal, rpVal, a)
}
num := rVal.NumField() //获取结构体有多少个字段
for i := 0; i < num; i++ {
tarVal := rTyp.Field(i).Tag.Get("json") //反序列化的字段
fmt.Println(i, ">>>", rVal.Field(i), ">>>", tarVal)
}
m.print()
//numM := rVal.NumMethod() //获取结构体有多少个字段
//rVal.Method(0).Call(nil)
//reflect.ValueOf(&m).Method(0).Call(nil)
println("\n")
}
}
func base5() {
{ /*
A.go存放被测试的函数package A
X_test.go存放测试用例(可以有多个_test)package A
func TestY(t *testing.T){//可以有多个函数
if ...
t.Fatalf("%v",)//打印错误的信息
t.Logf("")//打印正确信息
}
*/
}
{
var memo = make(map[int]string)
var lock sync.Mutex
goroutinef := func(n int) {
//捕获函数发出的异常,在协程中可以方防止协程错误导致崩溃
defer func() {
if err := recover(); err != nil {
fmt.Println(">>>", err)
}
}()
var s string = ""
for i := 0; i <= n; i++ {
s += strconv.Itoa(i)
}
lock.Lock()
memo[n] = s
lock.Unlock()
if n == 0 {
fmt.Println("n==", 1/n)
}
}
for i := 0; i <= 200; i++ {
go goroutinef(i) //开启协程,如果主线程执行完毕了,协程也会跟着退出
}
time.Sleep(time.Second * 1)
lock.Lock()
for i := 0; i <= 200; i++ {
fmt.Println(i, "\t>>>", memo[i])
}
lock.Unlock()
var n int
n = runtime.NumCPU()
fmt.Println("CPU个数", n)
runtime.GOMAXPROCS(n - 1) //设置可同时执行的最大cpu个数max=n,go1.8以后的版本默认默认运行在多核上
}
{
intChan := make(chan int, 10) //管道声明,可存10个int
var c <-chan int = make(chan int, 10) //read only
//var c chan<- int = make(chan int, 10) //write only
intChan <- 10 //写入数据
intChan <- 10
intChan <- 10
intChan <- 10
intChan <- 10
intChan <- 10
fmt.Println(<-intChan) //取出数据
//传统方法会发生阻塞
//for {
// v, ok := <-intChan
// fmt.Println(v, ok)
// if !ok {
// break
// }
//}
for {
flag := false
select {
case v := <-intChan:
fmt.Println("intChan", v)
case v := <-c:
fmt.Println("c", v)
default:
flag = true
fmt.Println("all empty")
//可使用label
break
}
if flag {
break
}
}
close(intChan) //关闭通道
//遍历管道要关闭管道
for i := range intChan {
fmt.Println(i)
}
writeChan := make(chan int, 20)
readChan := make(chan bool, 1)
writeChan <- 10
writeChan <- 10
writeChan <- 10
//write
go func(w chan int) {
for i := 0; i < 50; i++ {
w <- i
//time.Sleep(time.Millisecond * 100)
fmt.Println("write>>>", i)
}
close(w)
}(writeChan)
//read
go func(r chan bool, w chan int) {
for {
v, ok := <-w
time.Sleep(time.Millisecond * 100)
//fmt.Println("ok>>>", ok)
if !ok {
break
}
fmt.Println("read>>>", v)
}
r <- true
close(r)
}(readChan, writeChan)
for {
_, ok := <-readChan
if !ok {
break
}
//fmt.Println("read>>>", v)
}
}
}
func network() {
ipport := "127.0.0.1:8888"
server := func(ipport string) {
//read client input
process := func(conn net.Conn) {
defer conn.Close()
for {
fmt.Println("server>>>waiting client input>>>", conn.RemoteAddr().String())
buf := make([]byte, 1024)
n, e := conn.Read(buf)
if e == io.EOF {
fmt.Println("server>>>client quited", e)
return
}
fmt.Println(">>>server>>>read>>>", string(buf[:n]))
}
}
fmt.Println("server >>>listening")
l, e := net.Listen("tcp", ipport)
if e != nil {
fmt.Println("server>>>fail listening")
return
}
for {
fmt.Println("server>>>waiting connection")
c, e := l.Accept()
if e != nil {
fmt.Println("server>>>accept error")
}
fmt.Println("server>>>accept succ ip>>>", c.RemoteAddr().String())
go process(c)
}
defer l.Close()
fmt.Println("server>>>succ listening>>>", l)
}
//fmt.Println("<<<server>>> enter ip<<<")
//fmt.Scan(&ipport)
go server(ipport)
time.Sleep(time.Millisecond * 100)
client := func(ipport string) {
c, e := net.Dial("tcp", ipport)
if e != nil {
fmt.Println("client >>>dial error")
return
}
fmt.Println("client >>>conn succ>>>", c)
fmt.Println("<<<client >>>write something<<<")
reader := bufio.NewReader(os.Stdin)
line, e := reader.ReadString('\n')
if e != nil {
fmt.Println("client >>>NewReader error")
}
fmt.Println("client >>>write succ")
n, e := c.Write([]byte(line))
fmt.Println("client >>>write succ bytes=", n)
if e != nil {
fmt.Println("client >>>Write error")
}
}
//fmt.Println("<<<client>>> enter ip")
//fmt.Scan(&ipport)
go client(ipport)
for {
}
}
func redis() {
/*
D:\ProgramFiles\Redis-x64-3.0.504
redis-server.exe redis.windows.conf
//把redis服务作为一个注册为系统服务在后台运行
redis-server --service-install redis.windows.conf --service-name redis
启动redis服务(设置自启)
win + R 然后输入services.msc回车。打开服务找到redis服务
启动redis并把启动类型修改为自动(如果不是自动的话)
//cmd 登录
.\redis-cli -h 127.0.0.1 -p 6379
AUTH -[username] [password]
*/
}
func main() {
//base1()//变量、输入、打印
//base2()//条件、循环、函数
//base3()//数组、字典、结构体、类
//base4() //文件、cmd、json、反射
//base5() //单元测试、协程管道
//network()//不全
redis()
}