学习go

64 阅读7分钟

学习到的Go语言的基础内容,整体包括golang初识,golang的第一个程序,go项目的编译和构建,最后就是go语言的基础知识(一些语法基础)

golang初识 :

golang没有那些内容:

  1. 没有类(class) : 用结构体替代
  2. 没有方法重载
  3. 没有继承
  4. 没有枚举类型
  5. 没有try/catch
  6. 没有泛型

golang有什么:

  1. struct(结构体)
  2. 结构体的内嵌
  3. 常量
  4. defer/recover/panic
  5. interface{}
  6. 接口

golang特性 :

  1. 头等函数,允许将函数分配给变量,作为其他函数的入参,返回值,函数可以是对象,函数也可以是类型
  2. 并行操作非常方便,通过go关键字启动协程
  3. 通过通讯共享内容
  4. 多路复用,channel的多路复用

golang语言特性

Golang的优势

极简单的部署方式:可直接编译成机器码、不依赖其他库、直接运行即可部署。

静态类型语言,编译的时候可以检查出大多数问题。

语言层面的并发:天生的基因支持、充分的利用多核

go
复制代码
// Go 语言实现并发的代码
func goFunc(i int) {
    fmt.Println("goroutine ", i, " ...")
}
​
func main() {
    for i := 0; i < 1000; i++ {
        go goFunc(i) // 开启一个并发协程
    }
    time.Sleep(time.Second)
}

强大的标准库

runtime 系统调度机制、高效的 CG 垃圾回收、丰富的标准库

Golang 的应用场景

1、云计算基础设施领域:

代表项目:docker、kubernetes、etcd、consul、cloud flare CDN、七牛云存储 等。

2、基础后端软件:

代表项目:tidb、influxdb、 cockroach 等。

3、微服务

代表项目:go-kit、 micro、 monzo bank 的 typhon、bilibili 等。

4、互联网基础设施

代表项目:以太坊、hyperledger 等。

有编程经验如何快速学习go

  1. 那些内容是golang没有的
  2. 使用golang的特性的替代方案
  3. golang面向对象编程
  4. golang多态的实现

golang的第一个程序 :

go
复制代码
// hello.go
package main // 在go中,每个文件都必须归属于一个包
import "fmt" //引入一个包,包名fmt,引入该包后,就可以使用fmt包的函数,比如fmt.Println()
func main() { // func 是一个关键字,表示一个函数,main是函数名,是我们程序的入口
    fmt.Println("Hello World!")//调用fmt包中的函数Println()输出Hello World
}

在vscode中执行go文件:

法一 :

  1. 通过go build 命令对go文件进行编译,生成.exe可执行文件

    go
    复制代码
    D:\myBianCheng\vscProject\goproject\src\go_code\project01\main>go build hello.go

    也可以指定产生的exe文件名称 :

    go
    复制代码
    go build -o myhello.exe hello.go
    
  2. 运行hello.exe即可

    go
    复制代码
    D:\myBianCheng\vscProject\goproject\src\go_code\project01\main>hello.go
    

法二 :

可以通过go run 命令可以直接运行hello.go程序

go
复制代码
D:\myBianCheng\vscProject\goproject\src\go_code\project01\main>go run hello.go
Hello World!

go开发注意事项 :

  • go区分大小写
  • go的每条语句后面不用加分号
  • go编译器是一行行进行编译的,所以不能将多条语句写在一行,否则报错
  • go中如果定义了变量或者import了某个包,就一定要用,否则会报错

go项目构建及编译

一个Go工程中主要包含以下三个目录:

python
复制代码
    src:源代码文件
    pkg:包文件
    bin:相关bin文件

1: 建立工程文件夹 goproject

2: 在工程文件夹中建立src,pkg,bin文件夹

3: 在GOPATH中添加projiect路径 例 e:/goproject

4: 如工程中有自己的包examplepackage,那在src文件夹下建立以包名命名的文件夹 例 examplepackage

5:在src文件夹下编写主程序代码代码 goproject.go

6:在examplepackage文件夹中编写 examplepackage.go 和 包测试文件 examplepackage_test.go

7:编译调试包

go build examplepackage

go test examplepackage

go install examplepackage

这时在pkg文件夹中可以发现会有一个相应的操作系统文件夹如windows_386z, 在这个文件夹中会有examplepackage文件夹,在该文件中有examplepackage.a文件

8:编译主程序

go build goproject.go

成功后会生成goproject.exe文件

至此一个Go工程编辑成功。

go
复制代码
1.建立工程文件夹 go
$ pwd
/Users/***/Desktop/go
2: 在工程文件夹中建立src,pkg,bin文件夹
$ ls
bin        conf    pkg        src
3: 在GOPATH中添加projiect路径
$ go env
GOPATH="/Users/liupengjie/Desktop/go"
4: 那在src文件夹下建立以自己的包 example 文件夹
$ cd src/
$ mkdir example
5:在src文件夹下编写主程序代码代码 goproject.go
6:在example文件夹中编写 example.go 和 包测试文件 example_test.go
    example.go 写入如下代码:
​
    package example
​
    func add(a, b int) int {
        return a + b
    }
​
    func sub(a, b int) int {
        return a - b
    }
​
    example_test.go 写入如下代码:
​
    package example
​
    import (
        "testing"
    )
​
    func TestAdd(t *testing.T) {
        r := add(2, 4)
        if r != 6 {
            t.Fatalf("add(2, 4) error, expect:%d, actual:%d", 6, r)
        }
        t.Logf("test add succ")
    }
​
7:编译调试包
    $ go build example
    $ go test example
    ok      example    0.013s
    $ go install example
​
$ ls /Users/***/Desktop/go/pkg/
darwin_amd64
$ ls /Users/***/Desktop/go/pkg/darwin_amd64/
example.a    
8:编译主程序
    oproject.go 写入如下代码:
    package main 
​
    import (
        "fmt"
    )
​
    func main(){
        fmt.Println("go project test")
    }
​
    $ go build goproject.go
    $ ls
    example        goproject.go    goproject
​
       成功后会生成goproject文件
    至此一个Go工程编辑成功。
​
       运行该文件:
    $ ./goproject
    go project test

go基础知识 :

go转义字符 :

复制代码
\t
\n
\
\
\r

注释 :

提高代码的可阅读性

  1. 行注释 :

    // 注释内容

  2. 块注释 :

    /*

    注释内容

    */

go代码格式化 :

go
复制代码
// 显示格式化后的代码
gofmt hello.go
// 将格式化后的内容重写写入到文件中
gofmt -w hello.go

tab : 实现缩进,默认向右移动

shift + tab : 整体向左移动

csharp
复制代码
// 正确 :
func main() {
    fmt.Println("Hello World!")
}
// 错误 : 
func main() 
{
    fmt.Println("Hello World!")
}
​

4.一行最多不超过80个字符,超过请换行

dos常用指令

dos :

Disk Operating System 磁盘操作系统,

dos的基本操作原理 :

image-20230725171131866转存失败,建议直接上传图片文件

常见指令 :

  • dir : 查看当前目录详细信息

  • cd :

    bash
    复制代码
    cd /d D:\     : 进入到d:\目录
    cd \           : 返回到根目录
    cd ..          : 切换到上一级
    
  • md : 新建目录

    复制代码
    md ys100            : 新建一个目录
    md a1 b2 新建多个目录
    
  • rd : 删除目录

    bash
    复制代码
    rd ok100            : 删除空目录
    rd /q/s ok 200      : 删除目录以及下面的子目录文件,不带询问
    rd /s ok300         : 删除目录以及下面的子目录和文件,带询问
    
  • echo : 新建或追加内容到文件 :

    bash
    复制代码
    echo hello > d:\bac.txt
    
  • del : 删除文件

go变量

Golang 变量使用的三种方式:

  1. (1) 第一种:指定变量类型,声明后若不赋值,使用默认值

    csharp
    复制代码
    func main() {
        var i int
        fmt.Println("i=",i)
    }
    // 输出0,int 的默认值是0
    
  2. (2) 第二种:根据值自行判定变量类型(类型推导)

    dart
    复制代码
        var num = 9.14
        fmt.Println("num = ",num)
    
  3. 第三种:省略 var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误

    css
    复制代码
        s := "tom"
        fmt.Println("s = ",s)
    

多变量声明

go
复制代码
package main
import "fmt"func main(){
    // 该案例演示golang如何一次性声明多个变量
    //var nl,n2,n3 int
    // fmt.Println("n1=" ,n1, "n2=", n2, "n3=", n3)
    
    // 一次性声明多个变量的方式2
    // var n1,name , n3 = 10, "tom" ,888
    // fmt.Println("n1=",n1,"name=",name,"n3=",n3)// 一次性声明多个变量的方式3,同样可以使用类型推导
    n1,name , n3 :=100, "tom",888
    fmt.Println("n1=",n1,"name=", name,"n3=",n3)
}

全局变量 :

在go中,在函数外部定义的变量就是全局变量

go
复制代码
package main
import "fmt"var n1 = 100
var n2 = 200
var n3 = 300
// 上面的定义可以改为一次性声明
var (
    n4 = 400
    n5 = 500
)
func main(){
    fmt.Println("n1=",n1,"n2=",n2,"n3=",n3,"n4=",n4,"n5=",n5)
}

数据类型 :

值类型 :

变量直接存储值,内存通常在栈中分配

go
复制代码
    bool
    int(32 or 64), int8, int16, int32, int64
    uint(32 or 64), uint8(byte), uint16, uint32, uint64
    float32, float64
    string
    complex64, complex128
    array    -- 固定长度的数组

引用类型(指针类型) :

变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆 上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由 GC 来回收

go
复制代码
  slice   -- 序列数组(最常用)
  map     -- 映射
  chan    -- 管道
  指针
  interface

整形 :

分为int(有符号,默认类型) 和 uint(无符号)

小数/浮点型 :

css
复制代码
var p float32 = 89.12

分为 :

  • float32 : 单精度
  • flaot64 : 双精度,golang默认声明类型

两种表现形式 :

  • 十进制数形式:如:5.12 .512 (必须有小数点)
  • 科学计数法形式:如:5.1234e2 = 5.12 * 10 的 2 次方 5.12E-2 = 5.12/10 的 2 次方

字符类型

Golang 中没有专门的字符类型,如果要存储单个字符(字母),一般使用 byte 来保存。

字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。也 就是说对于传统的字符串是由字符组成的,而 Go 的字符串不同,它是由字节组成的。

go
复制代码
package main
​
import "fmt"func main() {
    var c1 byte = 'a'
    var c2 byte = '0' //字符0// 当我们直接输出byte值,就是直接输出对应的ascii码值
    fmt.Println("c1 = ", c1)
    fmt.Println("c2 = ", c2)
​
    // 要输出对应字符,就要格式化输出
    fmt.Printf("c1=%c c2 = %c\n", c1, c2)
​
}
​
  • Go 语 言 的 字 符 使 用 UTF-8 编 码 , 如 果 想 查 询 字 符 对 应 的 utf8 码 值 www.mytju.com/classcode/t…
  • 在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
  • 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的 unicode

bool类型

  • bool类型只允许去true和false两个值
  • bool类型占一个字节

string 类型

  • 基本介绍: 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本

    go
    复制代码
    package main
    ​
    import (
        "fmt"
        _ "strings"
    )
    ​
    func main() {
        var str string = "ysjhhasdjhfkj"
        // str[0] = 's' : 报错
        fmt.Println(str)
    }
    ​
    
  • 在golang中,字符是不可变的

  • 字符串的两种表现形式

    • 双引号 : 会识别转义字符

    • 反引号 : 以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果