go入门 | 青训营

53 阅读5分钟

安装 与 配置

入门文档项目地址

  1. 访问 go.dev/ ,点击 Download ,下载对应平台安装包,安装即可
  2. 如果无法访问上述网址,可以改为访问 studygolang.com/dl 下载安装
  3. 如果访问 github 速度比较慢,建议配置 go mod proxy,参考 goproxy.cn/ 里面的描述配置,下载第三方依赖包的速度可以大大加快

vscode居然下载文件在这 go.lnk

学习 Go 语言基础语法

空余时间阅读 Go语言圣经(中文版)

还是菜鸟靠谱

构造体

type Books struct {
    title string
    author string
    subject string
    book_id int
}
// 创建一个新的结构体
fmt.Println(Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407})
​
// 也可以使用 key => value 格式
fmt.Println(Books{title: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407})
​
// 忽略的字段为 0 或 空
fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"})
​
Book2.title = "Python 教程"

参数

  • 传值
printBook(Book2)
func printBook( book Books ) {
    fmt.Printf(book.title="change")
}
  • 传引用
printBook(&Book2)
func printBook( book *Books ) {
   fmt.Printf(book.title="change")
}

定义方法

type rect struct {
    width, height int
}
//构造体的方法
//r 相当于this
//*rect 表示使用*rect类型调用该方法
func (r *rect) area() int {
    r.height = 6
    return r.width * r.height
}
​
//构造体的方法,r相当于调用构造体的复制
func (r rect) perim() int {
    r.width = 9
    return 2*r.width + 2*r.height
}
​
r := rect{width: 10, height: 5}
area := r.area()   // 使用指针接收器调用方法,没有显式使用指针,但是 Go 会自动处理
perim := r.perim() // 使用值接收器调用方法
fmt.Println(r)

接口

  • 接口

    需要实现 area() float64

type Shape interface {
    area() float64
}
  • 实现结构1

隐式实现:如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口

type Rectangle struct {
    width  float64
    height float64
}
//值调用
func (r Rectangle) area() float64 {
    return r.width * r.height
}
  • 实现结构2
type Circle struct {
    radius float64
}
//指针调用
func (c *Circle) area() float64 {
    return 3.14 * c.radius * c.radius
}
  • 通过将接口作为参数来实现对不同类型的调用,从而实现多态
  • 接口类型变量可以存储任何实现了该接口的类型的值
func main() {
    
    var s Shape
    
    s = Rectangle{width: 10, height: 5}
    fmt.Printf("矩形面积: %f\n", s.area())
​
    s = &Circle{radius: 3}
    fmt.Printf("圆形面积: %f\n", s.area())
}
  • Shape 接口的 area 方法必须使用值接收器

  • 实现接口的构造体使用 值调用

     s = Rectangle{width: 10, height: 5} 
     s.area()
    
  • 实现接口的构造体要是 指针调用

    s = &Circle{radius: 3} //表明s 为指针类型
    s.area()
    

新建

单文件

同一个包下:

  • 方法和全局变量可以直接使用

不同包:

  • 需要 包名.方法() 调用
  • 不过嘛只有一个文件在main包下且只有一个main方法
创建 hello.go
//myhellogo\hello.go
package main //与文件夹名无关import "fmt" //导包时,不同包下要加 包名func main() {//一个文件夹下只有一个main
   fmt.Println("Hello, World!")
}
go run hello.gogo build hello.go 
//如果是普通包(非main包), 只做检查, 不产生可执行文件
//如果是main包,生成可执行文件, 默认生成的可执行文件名为项目名(go mod里面)

新建项目

使用mod

go env 命令 可以看到 GO111MODULE 字段

  • auto 如果在gopath/src下,但是存在go.mod文件,就采用的go mod包管理方式; 在gopath/src下,但没有go.mod文件, 采用以前默认的方式; 若未在gopath/src下, 自然是采用的go mod包管理方式(前提是需要go.mod文件存在)

  • on

    不管在不在gopath/src下,都采用的go mod包管理方式

  • off

    就是以前的默认方式(这时候项目必须放在gopath/src下),若需要引用外部包文件,使用go get命令下载下来。 比如在一个.go文件中,require (“github.com/gin-gonic/gin”) 那么使用go get github.com/gin-gonic/gin ,并且这个下载下来的资源会放在gopath/src下, 而使用go mod包管理的方式,下载下来的资源会放在gopath/pkg下,后边会用测试案例详细介绍如何操作。

gopath/src 管理

旧写法的项目一定要放在这里

package util
import("fmt")
func Test() {   //注意首字母大写, 不然无法调用,大写表示允许被调用
        fmt.Println("I'm pkg/util/Test()")
}  
package main
import("demo1/pkg/util")
func main() {
        util.Test()
}

这里主要分析import(“demo1/pkg/util”) , 对于以前的默认方式,也就是项目必须放到gopath/src下的原因, 其实它会在demo1/pkg/util前面自动加上gopath/src路径, 完整的写出来其实是gopath/src/demo1/pkg/util, 这也就是为什么必须放到gopath/src下。

go mod 管理

go mod init demo:生成,这就相当于命名空间了,其他同项目下的文件都可以使用import demo来导该项目的包

module demo
​
go 1.20
package main
import (
    "demo/util"
)
func main() {
        util.Test()
}
package util
import (
    "fmt"
)
func Test() {   //注意首字母大写, 不然无法调用,大写表示允许被调用
        fmt.Println("I'm pkg/util/Test()")
} 

demo用来替代了当下的绝对路径,在这里其实demo表示的是当前项目路径, 所以它并不依赖gopath/src, 你将项目移到其他位置, demo就会表示那个位置的绝对路径, demo可以换成任意字符, 比如你最开始用的是go mod init demo, 那么这里就要 import(“demo/pkg/util”), 可以在go.mod文件中对它(demo名称)进行修改。

其他:

  • 同一个文件夹下的包名要一致

  • 文件夹名称最好和包名一致

    • 不然有点麻烦

引用github上的包

  • go mod 访问联网包会下载到path

    • 使用 go get github.com/gin-gonic/gin, 然后这个资源会下载到gopath/src中
    • 或者:go mod tidy 下载所有
  • go mod 外部项目包可以重定向,比如

    • 导包:

      import("github.com/cnwyt/my_gotest/pkg/util")

    • .mod文件:

      require github.com/cnwyt/my_gotest v0.0.0

      replace github.com/cnwyt/my_gotest => C://my_gotest //这就是replace的用处,用于替换

依赖管理