Golang快速上手

背景

本文目的旨在,大家看完文章就能上手进行Golang的业务开发实现需求,属于一篇Golang速成,如果有相关基础,后边会再出一篇高级篇,用来给大家做一下比较深入的讨论。

技术架构

Golang的设计目标之一是提高开发效率和代码可维护性,其技术架构也反映了这一点。

标准库

标准库的数量和质量常常决定了我们在开发过程中的上线,和其他主流开发语言一样,Golang拥有丰富的标准库,涵盖了从输入/输出、字符串处理、网络编程到数据序列化等各个方面。这使得开发者可以快速构建功能齐全的应用程序,而无需依赖第三方库。

并发模型

Golang的并发模型基于goroutine和channel。Goroutine是轻量级的线程,创建和销毁的开销很小。Channel则用于在goroutine之间传递消息和数据,实现高效的并发编程。在使用channel来进行并发处理的时候,大家会发现实现极其简单,不同水平的开发人员写出的代码几乎相差无几。

静态类型

Golang是静态类型语言,这意味着所有变量的类型在编译时确定。

编译和工具链

Golang的编译器非常高效,可以快速编译代码生成可执行文件。Golang的工具链还包括自动化测试、代码格式化、静态分析等工具,进一步提高了开发效率。同时还包含了RPC这种框架下的十分简洁的上下游调用链,对于开发来说会是一个比较舒服的调用过程

基础知识

ok,热身完毕,现在我们来聊一下Golang的一些基础知识,保证大家看完后可以立马上手开发。
安装和配置环境
要开始使用Golang,首先需要安装Golang的开发环境。你可以从Golang官方网站下载并安装相应版本。安装完成后,配置环境变量:
下面展示一些 内联代码片

export PATH=$PATH:/usr/local/go/bin

第一个程序

一个典型的Golang程序如下:

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

上述代码定义了一个简单的main包,并在main函数中输出"Hello, World!"。

包管理

Golang的包管理是Golang极具特色的一个能力,相比于Java中多模块下多pom的管理方式,Golang的包管理更为简洁
每个包代表一个独立的功能模块,可以被其他包导入和使用。包的定义如下:


package math

func Add(a int, b int) int {
    return a + b
}

编译和运行

使用go run命令可以直接运行Golang程序,当然如果用开发工具的话直接点点就可以了:
go run main.go

使用go build命令可以编译程序生成可执行文件:
go build -o myapp main.go

数据类型

Golang提供了丰富的数据类型,包括基本类型和复合类型。
整数类型:int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64
浮点类型:float32, float64
布尔类型:bool
字符串类型:string
复合类型(非常重要,非常重要,非常重要,因为Golang中没有太花里胡哨的东西,下面三个复合类型就囊括了99.99%的开发中使用的数据类型)
数组:固定长度的同类型元素的集合
切片:动态数组,可以改变长度
映射(map):键值对集合
结构体(struct):自定义类型,将多个字段组合在一起
示例代码

package main

import "fmt"

func main() {
    // 基本类型
    var i int = 10
    var f float64 = 3.14
    var b bool = true
    var s string = "Golang"

    fmt.Println(i, f, b, s)

    // 数组
    var arr [5]int = [5]int{1, 2, 3, 4, 5}
    fmt.Println(arr)

    // 切片
    var slice []int = []int{1, 2, 3}
    fmt.Println(slice)

    // 映射
    var m map[string]int = map[string]int{"one": 1, "two": 2}
    fmt.Println(m)

    // 结构体
    type Person struct {
        Name string
        Age  int
    }

    var p Person = Person{Name: "Alice", Age: 25}
    fmt.Println(p)
}```

数组
数组是固定长度的同类型元素的集合。声明数组时需要指定长度。

var arr [5]int
arr[0] = 1
fmt.Println(arr)

切片
切片是动态数组,可以改变长度。切片比数组更灵活,使用更频繁。

slice := []int{1, 2, 3}
slice = append(slice, 4)
fmt.Println(slice)

映射

映射(map)是一种键值对集合。键和值可以是任意类型。
m := make(map[string]int)
m["one"] = 1
fmt.Println(m)

结构体
结构体(struct)是一种聚合数据类型,将多个字段组合在一起。注意一下,struct还可以当作一个类的专属名称来使用

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Bob", Age: 30}
fmt.Println(p)

//除此之外还可以这么用
func (Person *h)insert(int id){
  //逻辑放在这里
  //上面的参数就可以当作公有变量在这个类中使用
}

错误处理

Golang使用内置的error接口来处理错误。函数返回值通常包括结果和错误信息。这里错误处理还有一种defer的用法,可以来做一些兜底操作和处理,不过这篇文章主要是让大家快速上手和熟悉Golang这里就不做讲解了,感兴趣的大家可以自行搜索。
示例代码

package main

import (
    "errors"
    "fmt"
)

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

func main() {
    result, err := divide(4, 2)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }
}

开发常用

基础知识了解完毕就来聊一下开发中几乎必用的一些能力吧。

thrift

Thrift是一个用于跨语言服务开发的框架。Golang支持使用Thrift生成客户端和服务器代码。
安装Thrift
安装Thrift编译器:
brew install thrift
使用Thrift
定义Thrift接口文件,相当于Java中的swagger,但是这里更为直观例如service.thrift:

namespace go tutorial

service Calculator {
    i32 add(1: i32 num1, 2: i32 num2)
}

生成Golang代码:

thrift -r --gen go service.thrift

并发

Golang以其强大的并发模型而著称。Golang中的并发编程基于goroutine和channel。
Goroutine

Goroutine是轻量级的线程,使用go关键字启动。
go func() {
    fmt.Println("Hello from a goroutine")
}()
Channel
Channel用于在goroutine之间传递消息和数据。
ch := make(chan int)
go func() {
    ch <- 42
}()
fmt.Println(<-ch)

然后可以以此堆叠,因为Golang的特性,你堆叠几十个乃至上百个都不会影响性能,所以在开发的过程中就要求下游只提供最基础的查询,然后全用并发来拼接,最后在上游完成处理。
数据库
Golang提供了多种数据库驱动,可以连接和操作不同类型的数据库。常见的数据库驱动有database/sql和gorm。

连接数据库

使用database/sql连接和操作数据库:

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
    log.Fatal(err)
}
defer db.Close()

查询数据
执行SQL查询:

rows, err := db.Query("SELECT id, name FROM users")
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

for rows.Next() {
    var id int
    var name string
    if err := rows.Scan(&id, &name); err != nil {
        log.Fatal(err)
    }
    fmt.Println(id, name)
}

常见问题

在实际的Golang开发过程中,可能会遇到各种各样的问题。以下是一些常见问题及其解决方案。

Thrift版本问题

问题描述:
在使用Thrift进行跨语言服务开发时,可能会遇到Thrift版本不兼容的问题。这可能会导致生成的代码无法正常工作。
解决方案:
确保所有使用Thrift的项目使用相同的Thrift编译器版本。
使用go.mod文件来管理Thrift库的版本,确保所有依赖的一致性。
如果遇到版本不兼容的问题,可以尝试升级或降级Thrift编译器版本,或者手动修改生成的代码以兼容当前版本。
示例:
在项目的go.mod文件中指定Thrift库的版本:
module your_module_name

go 1.18

require (
github.com/apache/thrift v0.13.0
)

新引入依赖不生效

问题描述:
在项目中引入新的依赖包后,发现依赖包无法生效,导致编译错误或运行时错误。
解决方案:
确保已经正确添加新的依赖包,并运行了go mod tidy或go mod vendor命令来更新依赖。
检查项目的go.mod文件,确保新引入的依赖包已经被正确添加。
如果使用了IDE,尝试重启IDE以刷新依赖缓存。
确保没有使用旧版本的依赖包,可以尝试删除go.sum文件并重新运行go mod tidy。
示例:
在项目中引入新的依赖包并更新依赖:

go get github.com/gin-gonic/gin
go mod tidy(这个命令有事没事就可以敲一下,能解决7成左右的问题)

总结
本文介绍了Golang的基础知识,涵盖了从数据类型、数据结构、错误处理到并发编程和数据库操作的各个方面。通过阅读本文,读者应当能够掌握Golang的基本概念和编程技巧,并能够上手进行实际的开发。

package main

import (
    "database/sql"
    "errors"
    "fmt"
    "log"
    "os"

    _ "github.com/go-sql-driver/mysql"
)

func main() {
    // 基本数据类型
    var i int = 10
    var f float64 = 3.14
    var b bool = true
    var s string = "Golang"
    fmt.Println(i, f, b, s)

    // 数组
    var arr [5]int = [5]int{1, 2, 3, 4, 5}
    fmt.Println(arr)

    // 切片
    var slice []int = []int{1, 2, 3}
    slice = append(slice, 4)
    fmt.Println(slice)

    // 映射
    var m map[string]int = map[string]int{"one": 1, "two": 2}
    fmt.Println(m)

    // 结构体
    type Person struct {
        Name string
        Age  int
    }
    var p Person = Person{Name: "Alice", Age: 25}
    fmt.Println(p)

    // 错误处理
    result, err := divide(4, 2)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }

    // 日志
    log.Println("This is a log message")

    // 配置管理
    dbHost := os.Getenv("DB_HOST")
    fmt.Println("DB Host:", dbHost)

    // 并发
    ch := make(chan int)
    go func() {
        ch <- 42
    }()
    fmt.Println(<-ch)

    // 数据库连接
    db, err := sql.Open("mysql", "user:password@/dbname")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 数据库查询
    rows, err := db.Query("SELECT id, name FROM users")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    for rows.Next() {
        var id int
        var name string
        if err := rows.Scan(&id, &name); err != nil {
            log.Fatal(err)
        }
        fmt.Println(id, name)
    }
}

// divide 函数用于演示错误处理
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值