『Go 语言学习专栏』-- 第二期

时间:2022-05-31
本文章向大家介绍『Go 语言学习专栏』-- 第二期,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

golang-second.png


Golang 基础知识

大家好,我叫谢伟,是一名程序员。

刚刚工作一年,在编程领域是一名小兵。

对于初学者,或者说自学编程的人, 我非常理解他们自学的烦恼在哪里。

因为我也是从自学一路过来的。都会经历这些过程, 坚持下去就行, 相信我, 你幷不孤独.

如果你打算走编程的道路, 第一份工作一定要你喜欢, 或者说不讨厌,同时又是在编程的路上. 坚持下去, 相信我, 你幷不孤独.

怕的是你第一份工作因为诱惑, 走了其他路, 内心又想编程, 这种纠纠结结的状态,会让你过的很不舒服, 焦虑, 难以成长.

我2016年算是正式开始编程。那时小大小闹, 不正规, 怎么好玩怎么来, 学了忘, 忘了学...

我自学编程的时候都是写一些小的示例。没资源,没途径了解在企业里,到底需要些什么样的技能。于是一遍遍熟悉编程语言的特性。相信自学的编程的人大都是这样, 稍微厉害点的,肯琢磨的, 搞几个项目, 可见的项目出来, 就越来越熟练.

我直到毕业后,前大半年都是在学习,慢慢的接触一些东西。知道企业的一般开发流程是怎样的。企业需要什么样的技能,企业需要什么的技术。

我觉得我有必要分享出来一些企业的解决方式:

  • 会用些什么
  • 开发流程是什么样的
  • 需要什么样的人
  • 怎么技术选型 ...

当然这些受限于我自己的经验,但还是希望对大家有启发.

我的这个专栏,主要是想在自己已经使用 Golang 大半年写了几千行代码、搞过两个完整的项目之后,想更精深 Golang 这门语言的语言特性。

同时我正在看《代码大全》,有必要把一些好的编程思路注意事项分享出来。

这是我写这一系列文章的初衷。

在开始之前, 我再罗嗦两句: 1. 整体统一的代码风格非常重要 2. 刚开始就坚持一些好的编程风格

基础知识

上一节讲了 Golang 环境的搭建、项目的组织和包管理工具 govendor。

插播一个第三方下载包的工具: gopm, 这个工具解决的问题是: go get 一般是从 github 服务器, 或者 google 服务器上下载第三方库, 所以有时候网速慢,或者下载不成功.

地址: gopm

  • 下载 gopm: go get -u github.com/gpmgo/gopm
  • 再使用 gopm 下载第三方库: gopm get -g -v ****

这一节讲 Golang 的基础知识。主要包括:

  • 变量
  • 常量
  • 字符串
  • 数组
  • 切片
  • Map
  • 结构体
  • 函数
  • 方法
  • 分支
  • 循环

这些内容的熟悉就能开始写代码了。

编程和写作类似,这些基础知识就相当于写作中的文字。但为什么不同的人写的代码、文章存在很大的差异,有些人写的好,有些人写的不好。

这其实是代码的组织或者的文字的组织。

初学者往往不太注意这些:

比如:

  • 不太注意变量的命名
  • 不太注意函数的命名
  • 不太注意函数的组织方式
  • 不太注意项目的组织(即:代码文件的组织)
  • 不太注意整体的布局风格

那他们在注意什么? 注意实现, 一定程度上实现能促进初学者学习的热情. 相信我, 这些不注意,往往到最后会成为你的阻碍.

写代码,最后虽然是计算机执行,但是终归是人的产品,由人来阅读。

除非你对自己的编程水平很有信心,否则这些原则需要坚持。能不抽象就不抽象。做到“望文生义”,即看到你的代码大概就知道你想要干嘛,你的函数想要实现什么样的功能,你的项目想要实现什么样的功能。

这一点,其实之前我也不是太注意。最近不是在阅读《代码大全》嘛。

写一些代码片段可能不太能感受到这些原则能有什么样的益处。一旦你的项目越来越复杂的时候,你别头疼。

1 变量

变量的注意事项有下面几点:

  • 命名:

原则:

  1. 见文知意
  2. 规范:Golang 中采用驼峰式标准:numberOfClass
  3. 首字母大写:外部可访问;首字母小写:内部访问
  4. 长度适中
  5. 避免使用关键字
var ok bool
var value string
var number int
  • 声明及初始化

原则:

  1. 明确数据类型
  2. 少使用隐式声明
# Better
var Name string

# No Good

Name := "xieWei"

在函数内部可以使用 := 初始化,自动判断变量的类型。但是建议使用显式声明

  • 使用

原则:

  1. 变量声明,靠近使用处: 即你需要使用变量就在要使用的地方声明变量,而不是提前声明一大堆,或者远离使用变量的地方,不利于阅读
  2. 多个变量声明放一起
var (
  url string
  result []byte
  err error
  )

url = "http://www.baidu.com"
if result, err = http.Get(url); err!=nil{
  // do something
}

常用的布尔值变量名称:

  • done
  • found
  • ok
  • success
  • flag

使用对仗:

  • begin/start
  • first/last
  • locked/unlocked
  • min/max
  • next/previous
  • old/new
  • opened/closed
  • visible/invisible
  • source/target
  • source/destination
  • up/down

2 常量

常量注意这几点:

  • 关键字:const
const AppName = "App"

3 字符串

  • 短的
var Help string

Help = "Thank you for Your help."
  • 长的
var HelpMessage string  

HelpMessage = `
Hello Everone:
  Welcome to here.
  Today, we will learn how to learn golang.
`

字符串常用的操作:

库: strings

内置库的使用注意两点:

  • 函数的输入值及类型
  • 函数的输出值及类型
  • Contains: 判断是否包含字符串
func Contains(s, substr string) bool
  • Count: 输出字符串中自字符的个数
func Count(s, sep string) int
  • Index: 返回字符第一次出现的位置,不存在返回 -1
func Index(s, sep string) int
  • Join: 按给定的分隔符拼接一个字符串切片成字符串
func Join(a []string, sep string) string
  • LastIndex: 子串最后一次出现的位置
func LastIndex(s, sep string) int
  • ToLower: 將字符串全部小寫
func ToLower(s string) string
  • ToUpper: 將字符串全部大寫
func ToUpper(s string) string
  • Repeat: 重復字符串
func Repeat(s string, count int ) string
  • Replace: 替換
func Replace(s, old, new string, n int) string
  • TrimSpace: 去除字符串前後空格
func TrimSpace(s string) string
  • Split: 切割
func Split(s, sep string) []string 

4 数组

固定長度列表在Golang 里称之为数组.

長度不固定的里称之为切片.

var NumberList = [3]string

NumberList = [3]string{"Python", "Golang", "Java"}
  • 获取数组长度: len
  • 获取数组容量: cap

编程中,凡是可以使用if...else的都可以使用数组来遍历,再对遍历的值进行操作.

5. 切片

相当于不固定长的数组. 可以初始设置容量, 超过容量后,自动扩充.

  • len 获取长度
  • cap 获取容量

常用的操作:

  • slice
func main(){
    var (
        value []string
    )

    value = []string{
        "xieWei",
        "weiWei",
        "wuWei",
    }

    fmt.Print(value[1:])
}

>>> [weiWei wuWei]
  • append
func main(){
    var (
        value []string
    )

    value = []string{
        "xieWei",
        "weiWei",
        "wuWei",
    }

    value = append(value, "shenWei")
    fmt.Println(value)
}

>>> [xieWei weiWei wuWei shenWei]
  • range 操作
func main(){
    var (
        value []string
    )

    value = []string{
        "xieWei",
        "weiWei",
        "wuWei",
    }
    for index, i:= range value{
        fmt.Println(index, i)
    }
}

>>> 
0 xieWei
1 weiWei
2 wuWei

6. Map

字典: 键值型

  • 声明
func mapDeclare(key string, value string)map[string]interface{}{
    var (
        body map[string]interface{}
    )
    body = make(map[string]interface{})
    body[key] = value
    return body
}

func main(){
   fmt.Println(mapDeclare("name", "xieWei"))
}

>>> map[name:xieWei]
  • 遍历
func main(){
    var (
        body map[string]interface{}
    )
    body = make(map[string]interface{})
    body["name"] = "xiewei"
    body["age"] = 26
    body["university"] = "shanghaiUniversity"
    rangeMap(body)
}
func rangeMap(body map[string]interface{}) {
    for key, value := range body{
        fmt.Println(key, value)
    }
}

>>> 
name xiewei
age 26
university shanghaiUniversity

7. 结构体

结构体在 Golang 里面的作用非常大

  • 即是数据类型
  • 又可以有方法

作用相当于其他语言的类.

  • 声明
type MyExample struct {
    Name string
    Age int
    School string
}
func declare(){
    var (
        exampleStruct MyExample
    )
    exampleStruct.Name = "xieWei"
    exampleStruct.Age = 26
    exampleStruct.School = "shanghaiUniversity"
    fmt.Println(exampleStruct)
}

func main(){
    declare()
}

>>>
{xieWei 26 shanghaiUniversity}
  • 方法:

值传递 一般获取值: func (m MyExample) GetAttrName()string 指针传递一般改变值: func (m *MyExample) SetAttrAge(newAge int)

type MyExample struct {
    Name string
    Age int
    School string
}
func declare() MyExample {
    var (
        example MyExample
    )
    example.Name = "xieWei"
    example.Age = 26
    example.School = "shanghaiUniversity"
    fmt.Println(example)
    return example
}

func (m MyExample) GetAttrName()string{
    return m.Name
}
func (m *MyExample) SetAttrAge(newAge int){
    m.Age = newAge
}

func main(){
    test := declare()
    fmt.Println(test.GetAttrName())
    fmt.Println(test)
    test.SetAttrAge(18)
    fmt.Println(test)
}

>>> 
{xieWei 26 shanghaiUniversity}
xieWei
{xieWei 26 shanghaiUniversity}
{xieWei 18 shanghaiUniversity}
  • 匿名字段

即隐式的引入一个结构体的所有字段

type MyExample struct {
    Name string
    Age int
    School string
}
type OtherExample struct {
    MyExample
}


OtherExample 自动拥有 Name, Age, School 字段

8 函数

函数分为这麽几类:

  • 匿名函数
  • 结构体的方法
  • 普通函数

要写好函数注意下面几点:

  • 函数名称: 见文知意
  • 参数
  • 返回值
  • 匿名函数: 即没有名称的函数, 字面意思, 一般用来处理简单的函数
func main(){

    var NoNameFunc = func(name string) {fmt.Println(name)}
        NoNameFunc("xiewei")
}
  • 普通函数
func GetMaxNumber(number float64, other float64) float64 {
    return math.Max(number, other)
}

- func 关键字
- GetMaxNumber 函数名称
- number, other 参数 类型 float64
- 返回值类型 float64

9 分支/判断/循环

  • if 判断
  • if ...else / switch 分支
  • for 循环