2

【1-1 Golang】Go语言快速入门—基本语法

 1 year ago
source link: https://studygolang.com/articles/35856
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【1-1 Golang】Go语言快速入门—基本语法

tomato01 · 大约3小时之前 · 137 次点击 · 预计阅读时间 5 分钟 · 大约8小时之前 开始浏览    

  Go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。Go语言做到了在不损失应用程序性能的情况下降低代码的复杂性。

  Go语言语法简单,只有25个关键字,不需要耗费时间去学习记忆;数据类型包括布尔型,数字类型(整型、浮点型、复数),字符串,切片(数组),字典map,管道chan等,用起来还是比较顺畅的。

  Go语言天然具备并发特性,基于go关键字就能很方便的创建协程去执行一些并发任务,而其基于协程-管道的CSP并发编程模型,相比于传统复杂的多线程同步方案,可以说简单太多了。

  Go语言还具备垃圾回收能力,避免了应用层还需要关注内存的分配与释放,要知道在C/C++语言,内存管理可是可是让人非常头疼的。

  Go语言还提供了比较完善的标准库,比如我们只需要几行代码就能创建并启动一个HTTP服务。

  从本篇文章开始,将带领大家进入Go语言的世界。

  我们可以选择下载源码编译安装,下载安装包安装,下载编译好的可执行文件,下载地址为:https://golang.google.cn/dl/

  笔者本地安装的是go1.18.darwin-amd64.tar.gz,这是编译好的可执行文件,只需要解压即可,解压到目录 $HOME/Documents/go1.18。最后再配置下环境变量:

export GOROOT=$HOME/Documents/go1.18
export PATH=$PATH:$GOROOT/bin
export GOPATH=$HOME/Documents/gopath

  $GOROOT是Go的安装目录;$PATH是为了让我们可以在任意目录执行go命令;$GOPATH工作目录,通过go get命令下载的依赖包等就放在$GOPATH目录,基于gomod管理的依赖文件也会放在该目录下。

  安装配置完成后,执行go version验证是否安装成功。

  Go项目开发还少不了合适的编辑器,推荐使用Goland,下载地址为:https://www.jetbrains.com/go/。 安装完成后,打开Goland新建项目,新建main.go文件,编写经典的hello world:

package main

import "fmt"

func main() {
  fmt.Println("hello world")
}

  Go语言所有文件都必须指定其所在的包,如上"package main",我们称之为main包,当然包名也可以命名为其他名称(一般包名与当前所在目录/文件夹名称保持一致),而main包里的main函数为程序的入口函数。

  我们的代码肯定会依然其他文件,怎么引入呢?通过"import 包名"引入,引入后才能访问该包内函数/变量。如上面代码所示,fmt包是Go语言底层提供的格式化/IO包,Println函数打印变量到标准输出。

  Go语言数据类型包括布尔型,数字类型(整型、浮点型、复数),字符串,切片(数组),字典map,管道chan等,各类型变量的声明以及简单使用如下:

package main

import "fmt"

func main() {
  //变量声明
  var a int = 1 //var 声明并初始化变量, 类型int可以省略
  b := 1 //:= 声明+初始化变量
  b = 3 //=只能针对已有变量重新赋值
  fmt.Println(a, b)

  //字符串
  str1 := "hello "
  str2 := "world"
  fmt.Println(len(str1), str1 + str2)  //可以 +;len返回字符串长度

  //数组,容量固定
  arr := [5]int{1,2,3,4,5}
  arr[1] = 100 //数组元素访问
  fmt.Println(len(arr), arr) //len返回数组长度

  //切片,容量可以扩充,相当于动态数组
  slice := []int{1,2,3}
  slice[1] = 100 //切片元素访问
  slice = append(slice, 4, 5, 6) //append自动扩容
  fmt.Println(len(slice),cap(slice), slice) //len返回切片长度,cap返回切片容量

  //map,key-value结构
  score := map[string]int{
    "zhangsan":100,
    "lisi":99,
    "wangwu":98,
  }
  score["who"] = 90 //map赋值
  s, ok := score["who"] //map访问,s对应value值,ok标识该key是否存在(不存在返回空值)
  delete(score, "lisi") //删除map元素
  fmt.Println(s, ok, score)
}

  这里并没有给出管道chan的事例,这将在第二章并发模型详细介绍。当然除了Go语言提供的这些基本类型,我们也可以自定义类型,如接口,结构体等,这些也将在后面章节介绍。

  与其他语言类似,Go语言同样支持if/switch分支结构,for循环结构,如下面所示:

package main

import "fmt"

func main() {
  //if分支
  condition := true
  if condition {
    fmt.Println("true")
  }else{
    fmt.Println("false")
  }

  //wsith分支
  expr := "zhangsan"
  switch expr {
  case "zhangsan":
    fmt.Println("zhangsan")
  case "lisi":
    fmt.Println("lisi")
  default: //没有匹配到,默认执行
    fmt.Println("who")
  }

  //for循环
  for i := 0; i < 100; i ++ {
    if i /2 == 0 {
      fmt.Println("偶数")
    }
  }

  //无条件循环,死循环
  i := 0
  for {
    i ++
    fmt.Println("loop")
    if i > 100 { //检测条件,提前break退出循环
      break
    }
  }
}

  函数的定义,如名称,入参,返回值等基本概念这里就不做过多介绍了,Go语言与其他语言不同的地方在于,其支持多返回值(大部分语言只能返回一个值),以及可变参数(大部分语言其实也支持),另外Go语言还支持闭包(匿名函数),实例如下:

package main

import "fmt"

func main() {
  add, sub := addSub(4, 3)
  fmt.Println(add, sub)

  sum(1, 2, 3)

  nums := []int{1, 2, 3, 4}
  sum(nums...) //切片转可变参数,通过...实现

  //变量f为函数类型
  f := func (in string) {
    fmt.Println(in)
  }
  f("hello world") //执行函数

  //声明匿名函数,注意与上面却别,加括号直接执行该匿名函数
  func (in string) {
    fmt.Println(in)
  }("hello world")
}

//返回两个int值
func addSub(a, b int) (int, int){
  return a + b, a - b
}

//...表示参数数目可变
func sum(nums ...int) {
  total := 0
  //nums其实是切片类型([]int),for + range 可遍历切片元素
  for _, num := range nums {
    total += num
  }
  fmt.Println(total)
}

  Go语言天然具备并发特性,基于go关键字就能很方便的创建协程去执行一些并发任务。下面程序创建10个协程并发执行任务,主协程等待各子协程执行结束后,也自动退出:

package main

import (
  "fmt"
  "sync"
)

func main() {
  //WaitGroup用于协程并发控制
  wg := sync.WaitGroup{}
  //启动10个协程并发执行任务
  for i := 0; i < 10; i ++ {
    //标记任务开始
    wg.Add(1)
    go func(a int) {
      fmt.Println(fmt.Sprintf("work %d exec", a))
      //标记任务结束
      wg.Done()
    }(i)
  }
  //主协程等待任务结束
  wg.Wait()
  fmt.Println("main end")
}

  本篇作为深入理解Go语言系列第一篇,简单介绍了Go语言的基本语法,包括基本数据类型,分支结构,函数等基本概念,旨在让你对Go语言能有初步认识,从下一篇开始,我们将开始Go语言的全面探索。


有疑问加站长微信联系(非本文作者))

280

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK