Go 语言入门指南:基础语法和常用特性解析 | 青训营

72 阅读6分钟

1 什么是 Go 语言 ?

Go,也称为 Golang 或 Go 语言,是Google 开发的一种开源编程语言。软件开发人员在一系列操作系统和框架中使用 Go 来开发 Web 应用程序、云和网络服务以及其他类型的软件。

Go 是静态类型的、显式的,并且是在C编程语言之后建模的。由于 Go 语言的快速启动时间、低运行时开销以及无需虚拟机 ( VM ) 即可运行的能力,它已成为一种非常流行的用于编写微服务和其他用途的语言。此外,Go 还用于并发编程——一种一次无序或部分顺序执行多个任务的策略。

Go 语言的灵感来自Python的生产力和相对简单性。它使用 goroutines 或轻量级进程,以及一组包来进行高效的依赖管理。它旨在解决几个问题,包括缓慢的构建时间、不受控制的依赖性、重复工作、难以编写自动工具和跨语言开发。

2 Go 语言的特点

  1. 高性能、高并发: Go 语言的设计目标之一是实现高性能和高并发。Go 使得编写并发和并行代码变得更加容易,因为它通过 goroutines 和通道内置了对并发的支持,这与依赖线程和锁的 C++ 不同。它具有轻量级的协程(goroutine)和基于通道(channel)的并发模型,使得编写并发程序变得相对容易。Go 语言的调度器能够在多核处理器上有效地管理和调度协程,从而实现高效的并发执行。
  2. 语法简单、学习曲线平缓: Go 语言的语法简洁、清晰,致力于减少不必要的复杂性。Go 使用比 C++ 更简单、更现代的语法,摒弃了许多冗余的语法元素,使得代码更易读、易写。减少学习曲线,使新手能够相对轻松地入门。

如下所示仅仅两行代码就可以实现一个简单的http服务器

http.Handle( " / ", http.FileServer( http.Dir( ". " )))
http.ListenAndServe( " :8080",nil)
  1. 丰富的标准库: Go 语言附带了一个丰富而功能强大的标准库,涵盖了许多领域,包括文件操作、网络通信、加密、数据解析等。
  2. 完善的工具链: Go 语言提供了一套强大而一致的工具链,包括编译器、运行时、调试器、格式化工具等。
  3. 静态链接: Go 语言的程序可以被静态链接,这意味着可以将所有依赖的库和运行时嵌入到最终的可执行文件中,消除了在部署时依赖外部库的需求,使得部署变得更加简单和可控。
  4. 快速编译: Go 语言的编译速度非常快,开发者可以迅速进行编译-运行-测试循环。
  5. 跨平台: Go 语言支持多种操作系统和体系结构,可以轻松地在不同平台上编写和运行代码。编译后的程序可以在许多不同的操作系统上运行,而无需任何修改。
  6. 垃圾回收: Go 语言内置了自动的垃圾回收机制,开发人员不需要手动管理内存分配和释放。减轻了开发者的负担,减少了内存泄漏和资源管理问题的风险。

3 语法

3.1 Hello World

package main  

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

3.1.1 Hello World分析

  • 第一行 package main 代表这个文件属于 main 包的一部分,main 包也就是程序的入口包。
  • 第三行导入了标准库里面的 fmt 包。这个包主要是用来往屏幕输入输出字符串、格式化字符串。
  • import 下面是 main 函数,main 函数的话里面调用了 fmt.Println 输出 helloword

3.1.2 Hello World运行

有两种方法

  • 使用go run helloword.go直接运行。
  • 使用 go build 编译成二进制。再直接./helloword就可以运行。

3.2 变量与常量

3.2.1 变量与常量的声明

在Go中,需要先声明变量,然后才能使用。可以使用关键字var来声明变量。格式有两种:

var variable type

var variable type =value

var variable =value

声明常量将var替换为const即可。

对于变量还可以用短声明方式,如下:

variable :=value

3.2.2 类型

从两个方向列举GO的部分常用类型

  • 基本类型
    • 整数类型(int、int8、int16、int32、int64)
    • 浮点数类型(float32、float64)
    • 布尔类型(bool)
    • 字符串类型(string)
  • 复合类型
    • 数组([size] type)
       var variable [size]type
      
       variable := [size]type{val1,val2,...}
       
      
      
    • 切片([] type)
       var variable []type
      
       variable := []type{val1,val2,...}
      
       variable=append(variable,val)
      
       variable[beginIndex:endIndex]//切片
      
      
    • 映射(map[type1]type2)
       var variable map[type1]type2
      
       variable := make(map[type1]type2 )
      
       variable[key]=val2
      
       r,ok:=variable[val1]//判断key是否存在
      
       delete(variable,key)//删除key
      
      
    • 函数 (func name (paramete1r type1,...) returnType)
       variable:=func (paramete1r type1,...) returnType{
      
       ...
      
       }
      
       func name (paramete1r type1,...)returnType{
      
       ...
      
       }
      
       //错误处理
      
       func name (paramete1r type1,...)returnType,errorType{
      
       ...
      
       return val,err
      
       }
      
      
    • 结构体(struct{variable type...})
       type name struct{
      
       variable type
      
       ...
      
       }
      
       variable:=structType{initialize}
      
      
    • 方法(func (variable structType)name(paramete1r type1,...) returnType)
       //非指针类型
      
       func (variable structType)name (paramete1r type1,...)returnType{
      
       ...
      
       }
      
       //指针类型
      
       func (variable *structType)name (paramete1r type1,...)returnType{
      
       ...
      
       }
      
      
    • 指针(* type)
       var variable1=&variable2
      
       func name (paramete1r *type1,...)
      
       name(&variable2)
      

3.3 控制语句

控制语句包括以下。注意,GO的循环语句没有while

  • 条件语句:if、if else
  • 循环语句:for
  • 选择语句:switch

3.3.1 条件语句结构

 if condition{

 ...

 }else{

 ...

 }

3.3.2 循环语句结构

  • 死循环
 for{

 ...

 }
  • 经典 while循环
for condition{

...

}
  • 经典C for循环
 for initialize;condition;increment{

 ...

 }
  • 增强for循环
 for index,variable:=range DataSet{

 ...

 }

3.3.3 选择语句格式

  • 经典switch(注意,不需要用break打断,如需要继续运行下一个case的话需要加fallthrough
     switch variable {

     case val1:

     ...

     case val2:

     ...

     default:

     ...

     }
  • 增强型switch
     switch {

     case condition1:

     ...

     case condition2:

     ...

     default:

     ...

     }
  • type-switch型
     switch variable.(type) {

     case type1:

     ...

     case type2:

     ...

     default:

     ...

     }

4 标准库

4.1 输入输出

4.1.1 输出

调用fmt包里面的Println(variable1,...)或Printf(formatString,variable1,...),Printf强于C,它里面有%v用于输出任意类型数据,以下为%v的输出格式:

%v 值

%+v 字段和值

%#v 类型名称、字段和值

3.4.2 输入

调用fmt包里面的Scan(&variable1,...)或Scanf(formatString,&variable1,...)

4.2 JSON处理

使用buf,err:=json.Marshal(structVariable)序列化结构体,使用err:=json.Unmarshal(buf,&structVariable)反序列化。如果要设置json字段风格的话,则在定义结构体时需要定义结如下所示格式:

 {

 variable1 type1 `json:"jsonName"`

 ...

 }

4.3 时间处理

使用time.Now()获取当前时间,使用timevariable.Format("Jan 2, 2006 at 3:04pm")格式化时间字符串

4.4 数字解析

 strconv.ParseFloat(floatString, size)

 strconv.ParseInt(intString, size)

 strconv.ParseInt(intScaleString, scale, size)//任意进制整型数转换,若scale=0,则会推测intScaleString的进制

 strconv.ParseUint(intScaleString, scale, size)

 strconv.Atoi(decimalismString)//10 进制整型数转换

4.5 进程信息

 fmt.Println( os.args)//得到程序执行的时候的指定的命令行参数

 fmt.Println( os.Getenv ("PATH" ))

 fmt.Println( os. Setenv( "AA",“BB" ))//写入环境变量

 buf,err := exec.Command( " grep", "127.0.0.1","/etc/hosts" ).CombinedOutput()//启动子进程获取输入输出