go语言基础知识汇总

发布时间:2020-04-30 23:22:39 作者:PowerMichael
来源:网络 阅读:420

一、go语言简介

3.3 内置函数、递归函数、闭包

内置函数

Slice的数据结构
Type slice struct {
    ptr *[5]type
    len int
    cap int
}
Cap:不指定的话,默认为2^0 2^1 2^2 2^n n为元素的个数
  1. 通过make来创建切片(另一种通过数组创建切片)
    • var slice []type = make([]type, len)
    • slice := make([]type, len)
    • slice := make([]type, len, cap)
  2. 用append内置函数操作切片,当切片容量不够,会自动扩容,创建一个新的地址。
  3. For range 遍历切片
  4. 切片拷贝
  5. string与slice
    • string底层就是一个byte的数组,因此,也可以进行切片操作
      Type string struct {
      ptr *[5]byte
      len int
      }
    • 想要改变string中的字符值,首先需要把字符串转换成byte切片
  6. 排序和查找操作
    • sort.Ints对整数进行排序, sort.Strings对字符串进行排序, sort.Float64s对浮点数排序
    • sort.SearchInts(a []int, b int) 从数组a中查找b,前提是a必须有序
    • sort.SearchFloats(a []float64, b float64) 从数组a中查找b,前提是a必须有序
    • sort.SearchStrings(a []string, b string) 从数组a中查找b,前提是a必须有序
      map数据结构

  7. key-value的数据结构,又叫字典或关联数组
    • 声明 var a map[string]string
    • 声明是不会分配内存的,初始化需要make
  8. map相关操作
    • var a = map[string]string{"key":"value"}
    • a = make(map[string]string, 10)
    • a[“hello”] = “world” //插入或者更新
    • Val, ok := a[“hello”] // 查找
    • for k, v := range a //遍历
    • delete(a, “hello”) //删除
  9. map是引用类型
  10. slice of map
    • 字典类型的数组
    • Map类型的slice初始化
      Items := make([]map[int][int], 5)
      For I := 0; I < 5; i++ {
      items[i] = make(map[int][int])
      }
  11. map排序
    • a. 先获取所有key,把key进行排序
    • b. 按照排序好的key,进行遍历
  12. Map反转
    • a. 初始化另外一个map,把key、value互换即可
      3.5 package介绍

  13. golang中的包
    • a. golang目前有150个标准的包,覆盖了几乎所有的基础库
    • b. golang.org有所有包的文档,没事都翻翻
  14. 线程同步
    • a. import(“sync”)
    • b. 互斥锁, var mu sync.Mutex
    • c. 读写锁, var mu sync.RWMutex
    • d. 为什么要有锁:十字路口是公有的资源,红绿灯就是锁。为了避免小车争抢资源就要上锁。
  15. 课后作业
    实现一个冒泡排序、选择排序、插入排序、快速排序(参考书籍及搜索引擎)
    3.6 结构体&方法&接口
    结构体的特点

    1. 用来自定义复杂数据结构
    2. struct里面可以包含多个字段(属性)
    3. struct类型可以定义方法,注意和函数的区分
    4. struct类型是值类型
    5. struct类型可以嵌套
    6. Go语言没有class类型,只有struct类型
      结构体的定义以及初始化
  16. struct 声明:
  17. struct 中字段访问:和其他语言一样,使用点
  18. struct定义的三种形式:
    1. var stu Student
    2. var stu *Student = new (Student)
    3. var stu *Student = &Student{}
      • 其中2和3返回的都是指向结构体的指针,访问形式:a. stu.Name、stu.Age和stu.Score或者 (stu).Name、(stu).Age等
  19. struct的内存布局:struct中的所有字段在内存是连续的,布局如下:
  20. 链表定义
    • 每个节点包含下一个节点的地址,这样把所有的节点串起来了,通常把
      链表中的第一个节点叫做链表头
      type Student struct {
      Name string
      Next* Student
      }
  21. 双链表定义
    • 如果有两个指针分别指向前一个节点和后一个节点,我们叫做双链表
      type Student struct {
      Name string
      Next* Student
      Prev* Student
      }
  22. 二叉树定义
    • 如果每个节点有两个指针分别用来指向左子树和右子树,我们把这样的结构叫做二叉树
type Student struct {
       Name string
       left* Student
       right* Student
}
  1. 结构体是用户单独定义的类型,不能和其他类型进行强制转换
  2. golang中的struct没有构造函数,一般可以使用工厂模式来解决这个问题
type student struct {
    Name string
    Age     int
}

func NewStudent(name string, age int) *student {
    return &student{
        Name:name,
        Age:age,
    }
}
func main()  {
    s := new(student)
    a := NewStudent("tony", 23)
    s = a
    fmt.Println(*s)
    fmt.Println(*a)

}
  1. 再次强调:
    • make 用来创建map、slice、channel、interface,new用来创建值类型
  2. 我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的机制获取到,最常用的场景就是json序列化和反序列化
type student struct {
    Name stirng  "this is name field"
    Age int      "this is age field"
}
  1. 结构体中字段可以没有名字,即匿名字段
type Train struct {
        Car
        Start time.Time
        int
}
3.7 方法

  1. Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是struct
    • 定义:func (recevier type) methodName(参数列表)(返回值列表){}
  2. 方法的调用
type A struct {
    a int
}

func (this A) test() {
    fmt.Println(this.a)
}

var t A
t.test()
  1. 方法和函数的区别
    • 函数调用: function(variable, 参数列表)
    • 方法调用:variable.function(参数列表)
  2. 指针receiver vs 值receiver
    • 本质上和函数的值传递和地址传递是一样的
  3. 方法的访问控制,通过大小写控制
  4. 继承
    • 如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现了继承。
  5. 组合和匿名字段
    • 如果一个struct嵌套了另一个有名结构体,那么这个模式就叫组合
  6. 多重继承
    • 如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的方法,从而实现了多重继承。
  7. 实现String()
    • 如果一个变量实现了String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出。
      3.8 接口
      接口的定义

  8. interface类型可以定义一组方法,但是这些方法不需要实现。并且interface不能包含任何变量。
  9. 定义接口
    type example interface {
    Method1(parse1) return1
    method2(parse1) return1
    }
  10. interface类型默认是一个指针
  11. 接口实现
    • a. Golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,golang中没有implement类似的关键字
    • b. 如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个接口。
    • c. 如果一个变量只含有了1个interface的方部分方法,那么这个变量没有实现这个接口。
  12. 多态
    一种事物的多种形态,都可以按照统一的接口进行操作
  13. 接口嵌套
    一个接口可以嵌套在另外的接口
package main

type ReadWrite interface {
    Read()
    Write()

}

type Lock interface {
    Lock()
    Unlock()
}

type File interface {
    ReadWrite
    Lock
    Close()
}

8.类型断言,由于接口是一般类型,不知道具体类型,如果要转成具体类型,可以采用以下方法进行转换:

var t int 
var x interface{}
x = t
y, ok := x.(int) //转成int
if ok {...}
switch b := x.(type) {
    case int:
        fmt.Println("int:", b)
    case string:
        fmt.Println("string", b)
    default:
        fmt.Println("i don't know")
    }
  1. 空接口 interface{},空接口没有任何方案,所有类型都实现了空接口,可以使用空接口
var a int
var b interface{}
b  = a
  1. 判断一个变量是否实现了指定接口

    • if sv, ok := v.(Stringer); ok {}
  2. 问题
      1. 指针类型和值类型的区别
      1. 实现一个通用的链表类
      1. 实现一个负载均衡调度算法,支持随机、轮训等算法
      1. 变量slice和接口slice之间赋值操作,for range???
        3.9 反射

  3. 反射:可以在运行时动态获取变量的相关信息Import (“reflect”)
    • a. reflect.TypeOf,获取变量的类型,返回reflect.Type类型
    • b. reflect.ValueOf,获取变量的值,返回reflect.Value类型
    • c. reflect.Value.Kind,获取变量的类别,返回一个常量
    • d. reflect.Value.Interface(),转换成interface{}类型
    • 变量 <--> interface <--> Reflect.Value
  4. 获取变量的值
    • reflect.ValueOf(x).Float()
    • reflect.ValueOf(x).Int()
    • reflect.ValueOf(x).String()
    • reflect.ValueOf(x).Bool()
  5. 通过反射的来改变变量的值
    • reflect.Value.SetXX相关方法,比如:
    • reflect.Value.SetFloat(),设置浮点数
    • reflect.Value.SetInt(),设置整数
    • reflect.Value.SetString(),设置字符串
package main

import (
    "fmt"
    "reflect"
)

func main() {

    var a float64
    fv := reflect.ValueOf(&a)
    fv.Elem().SetFloat(3.3)
    fmt.Printf("%v\n", a)
}
fv.Elem()用来获取指针指向的变量
  1. 用反射操作结构体 ???
    • a. reflect.Value.NumField()获取结构体中字段的个数
    • b. reflect.Value.Method(n).Call来调用结构体中的方法
      3.9 终端以及文件操作
  2. 终端读写
    • os.Stdin:标准输入
    • os.Stdout:标准输出
    • os.Stderr:标准错误输出
  3. 带缓冲区的读写:
    • var inputReader *bufio.Reader //声明一个结构体类型的变量
    • inputReader = bufio.NewReader(os.Stdin) //读取标准输入
    • input, err = inputReader.ReadString('\n') // 读取换行
  4. os.File封装所有文件相关操作,之前讲的 os.Stdin,os.Stdout, os.Stderr都是*os.File
    • 打开一个文件进行读操作: os.Open(name string) (*File, error)
    • 关闭一个文件:File.Close()
    • bufio.NewReader //构造一个reader结构体
    • inputReader.ReadString //逐行读取
    • ioutil.ReadFile(inputFile) //读取整个文件
    • ioutil.WriteFile(outputFile,buf,0x644) //写入整个文件
    • gzip.NewReader(fi) //构造一个压缩文件的reader结构体
  5. 文件写入
    • os.OpenFile(“output.dat”, os.O_WRONLY|os.O_CREATE, 0666)
    • 第二个参数:文件打开模式:
    • 第三个参数:权限控制:
    • bufio.NewWriter(outputFile) //构建一个写入文件的writer
    • outputWriter.WriteString(outputString) //写入文件
    • outputWriter.Flush() 提交
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main()  {
    inputFile, err := os.Open("file")
    if err != nil {
        fmt.Printf("open file err:%v\n", err)
        return
    }

    defer inputFile.Close()

    inputReader := bufio.NewReader(inputFile)
    for {
        inputString, readerError := inputReader.ReadString('\n')
        if readerError == io.EOF {
            return
        }
        fmt.Printf("the input was %s", inputString)
    }

}
//读取以及写入整个文件
package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

func main()  {
    inputFile := "file"
    outputFile := "output_file"
    buf, err := ioutil.ReadFile(inputFile)
    if err != nil {
        fmt.Fprintf(os.Stderr, "File Error:%s\n", err)
        return
    }
    fmt.Printf("%s\n",string(buf))
    err = ioutil.WriteFile(outputFile,buf,0x644)
    if err != nil {
        panic(err.Error())
    }

}
//读取压缩文件
gzip.NewReader(fi)
//写入文件
package main

import (
    "bufio"
    "fmt"
    "os"
)

func main()  {
    outputFile, outputErr := os.OpenFile("new_file", os.O_WRONLY|os.O_CREATE,0666)
    if outputErr != nil {
        fmt.Printf("An error occurred with file creation\n")
        return
    }
    defer outputFile.Close()
    outputWriter := bufio.NewWriter(outputFile)
    outputString := "hello world!\n"
    for i:= 0;i < 10; i++ {
        outputWriter.WriteString(outputString)
    }
    outputWriter.Flush()
}
  1. 拷贝文件 io.Copy(dst, src)
  2. os.Args是一个string的切片,用来存储所有的命令行参数
  3. flag包的使用,用来解析命令行参数:
    flag.BoolVar(&test, "b", false, "print on newline")
    flag.StringVar(&str, "s", "", "print on newline")
    flag.IntVar(&count, "c", 1001, "print on newline")
package main

import (
    "flag"
    "fmt"
)

func main()  {
    var test bool
    var str string
    var count int

    flag.BoolVar(&test, "b", false, "print on newline")
    flag.StringVar(&str, "s", "hello", "print on newline")
    flag.IntVar(&count, "c", 1001, "print on newline")
    flag.Parse()

    fmt.Println(test,str,count)
}
package main

import (
    "bufio"
    "fmt"
    "os"
)

//带缓冲的区的终端读写
func main()  {
    fmt.Fprintf(os.Stdout,"%s\n","hello world!-unbuffered")
    buf := bufio.NewWriter(os.Stdout)
    fmt.Fprintf(buf, "%s\n", "hello world!-buffered" )
    buf.Flush()
}

四、中阶知识

4.1 json数据协议
  1. golang --> json字符串 --> 网络传输 --> 程序 --> 其他语言
    1. 导入包:Import “encoding/json”
    2. 序列化: json.Marshal(data interface{}) //json化
    3. 反序列化: json.UnMarshal(data []byte, v interface{}) //解析json
  2. json序列化结构体
  3. json序列化map
    4.2 错误处理
  4. 定义错误 var errNotFound error = errors.New("Not found error")
  5. 自定义错误
  6. 如何判断自定义错误
  7. pannic 这一部分参考俯瞰四维

    五、并发编程

    六、高阶编程

    6.1 tcp编程
    6.2 redis

    redis是个开源的高性能的key-value的内存数据库,可以把它当成远程的数据结构。支持的value类型非常多,比如string、list(链表)、set(集合)、hash表等等。redis性能非常高,单机能够达到15w qps,通常适合做缓存。使用第三方开源的redis库: github.com/garyburd/redigo/redis

    • 链接redis c, err := redis.Dial("tcp", "localhost:6379")
    • Set 接口 _, err = c.Do("Set", "abc", 100) r, err := redis.Int(c.Do("Get", "abc"))
    • Hash表 _, err = c.Do("HSet", "books", "abc", 100) r, err := redis.Int(c.Do("HGet", "books", "abc"))
    • . 批量Set _, err = c.Do("MSet", "abc", 100, "efg", 300) r, err := redis.Ints(c.Do("MGet", "abc", "efg"))
    • 过期时间 _, err = c.Do("expire", "abc", 10)
    • 队列操作 _, err = c.Do("lpush", "book_list", "abc", "ceg", 300) r, err := redis.String(c.Do("lpop", "book_list"))
      6.3 http编程
      特点

    • a. Go原生支持http,import(“net/http”)
    • b. Go的http服务性能和nginx比较接近
    • c. 几行代码就可以实现一个web服务
  8. 处理http请求
    使用 net/http 包提供的 http.ListenAndServe() 方法,可以在指定的地址进行监听, 开启一个HTTP,服务端该方法的原型:func ListenAndServe(addr string, handler Handler) error <br>
    第二个参数表示服务端处理程序, 通常为空,这意味着服务端调用 http.DefaultServeMux 进行处理,而服务端编写的业务逻 辑处理程序 http.Handle() 或 http.HandleFunc() 默认注入 http.DefaultServeMux 中
  9. 处理https请求 func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error
  10. 路由 http.HandleFunc()方法接受两个参数
    • 第一个参数是HTTP请求的 目标路径"/hello",该参数值可以是字符串,也可以是字符串形式的正则表达式
    • 第二个参数指定具体的回调方法,比如helloHandler
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte(“hello beifeng!”))
    })
  1. post访问
resp, err:=http.Get(“.....”)

defer resp.Body.Close()

body,err:=ioutil.ReadAll(resp.Body)

fmt.Println(string(body))
  1. post访问
resp, err:=http.Post(“.....”, ”application/x-www-form-urlencoded”, strings.NewReader(“..=...”))

defer resp.Body.Close()

body,err:=ioutil.ReadAll(resp.Body)

fmt.Println(string(body))
6.4 正则表达式

Go语言标准库内建提供了regexp包

.   匹配除换行符以外的任意字符
\w  匹配字母或数字或下划线或汉字
\s  匹配任意的空白符
\d  匹配数字
\b  匹配单词的开始或结束
^   匹配字符串的开始
$   匹配字符串的结束
*   重复零次或更多次
+   重复一次或更多次
?   重复零次或一次
{n}     重复n次
{n,}    重复n次或更多次
{n,m}   重复n到m次
捕获 (exp)    匹配exp,并捕获文本到自动命名的组里

(?<name>exp)    匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)

(?:exp)         匹配exp,不捕获匹配的文本,也不给此分组分配组号
func Match(pattern string, b []byte) (matched bool, err error)
func MatchString(pattern string, s string) (matched bool, err error)
func MustCompile(str string) *Regexp
func (re *Regexp) FindAllString(s string, n int) []string
https://my.oschina.net/kuerant/blog/199146
6.5 mysql编程
  1. mysql驱动
    https://github.com/Go-SQL-Driver/MySQL

  2. sqlx
    • database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
    • r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "stu001", "man", "stu01@qq.com")
    • err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1)
    • _, err := Db.Exec("update person set username=? where user_id=?", "stu0001", 1)
    • _, err := Db.Exec("delete from person where user_id=?", 1)
6.6 beego框架

beego.me

beego框架之请求数据处理

推荐阅读:
  1. python 基础知识汇总
  2. Go语言中channel的基础知识

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

golang golang基础知识 go语言基础

上一篇:数据为王的时代-----大数据

下一篇:ELK(ElasticSearch+Logstash+Kibana)+redis日志收集分析系统

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》