golang学习笔记——基础01

文章目录

  • golang概述
    • Go 语言特色
    • Go 语言用途
  • Go 语言结构
    • 执行 Go 程序
  • Go 语言包管理01
  • Go 语言包管理02
  • Go 语言基础语法
    • Go 标记
    • 行分隔符
    • 注释
    • 标识符
    • 字符串连接
    • 关键字、预定义标识符
    • Go 语言的空格
    • 格式化字符串
  • Go 语言数据类型
    • 数字类型
    • 浮点型
    • 其他数字类型
  • Go 语言变量
    • 变量声明
    • 零值
    • 多变量声明
    • 值类型和引用类型
    • 简短形式
  • Go 语言常量
    • iota
      • 几个常见的iota示例:
  • 参考资料

golang概述

golang学习笔记——基础01_第1张图片
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。

Go 语言特色

- 简洁、快速、安全
- 并行、有趣、开源
- 内存管理、数组安全、编译迅速

Go 语言用途

Go语言具有以下几个主要用途:

  1. 服务端开发:Go语言具备高效的并发处理能力和优秀的网络编程库,非常适合开发高并发的服务端程序,例如Web应用、API服务、微服务等。

  2. 分布式系统:Go语言的轻量级特性使其非常适合构建分布式系统,例如分布式消息队列、分布式存储系统、分布式计算等。

  3. 网络编程:Go语言提供了丰富的网络编程库,使其成为开发网络应用的理想选择,例如构建高性能的TCP/UDP服务器、实现自定义的网络协议等。

  4. 并发编程:Go语言天生支持并发编程,通过 goroutine 和 channel 实现简单而高效的并发模型,适合编写高性能的并发程序、任务调度器等。

  5. 嵌入式系统:Go语言的静态编译特性使其适用于嵌入式系统开发,可以用于开发物联网设备、嵌入式工具等。

  6. 跨平台开发:Go语言的编译器可以将Go代码编译为机器码,因此可以在不同操作系统和平台上运行,使其非常适合跨平台开发。

总的来说,Go语言是一门简洁高效的编程语言,适用于各种应用领域,特别是对性能和并发要求较高的场景。

Go 语言结构

Go 语言的基础组成有以下几个部分:

  • 包声明
  • 引入包
  • 函数
  • 变量
  • 语句 & 表达式
  • 注释

接下来让我们来看下简单的代码,该代码输出了"Hello World!":

package main

import "fmt"

func main() {
   /* 这是我的第一个简单的程序 */
   fmt.Println("Hello, World!")
}

让我们来看下以上程序的各个部分:

  1. 第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。
  2. 下一行 import “fmt” 告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数。
  3. 下一行 func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。
  4. 下一行 // 是注释,在程序执行时将被忽略。单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段。
  5. 下一行 fmt.Println(…) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n。
    使用 fmt.Print(“hello, world\n”) 可以得到相同的结果。
    Print 和 Println 这两个函数也支持使用变量,如:fmt.Println(arr)。如果没有特别指定,它们会以默认的打印格式将变量 arr 输出到控制台。
  6. 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public)
    标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。

执行 Go 程序

执行 Go 程序

$ go run hello.go
Hello, World!

生成二进制文件

$ go build hello.go 
$ ls
hello    hello.go
$ ./hello 
Hello, World!

注意

package main

import "fmt"

func main()  
{  // 错误,{ 不能在单独的行上
    fmt.Println("Hello, World!")
}

报错

# command-line-arguments
./main.go:5:6: missing function body
./main.go:6:1: syntax error: unexpected semicolon or newline before {

Go 语言包管理01

在Go语言中,GOPATH是一个环境变量,用于指定Go的工作目录。

以下是使用GOPATH的一般步骤:

  • 设置GOPATH环境变量:首先,需要将GOPATH环境变量设置为你的Go工作目录的路径。你可以选择将其设置为任意的目录路径,例如 /Users/username/go(以 macOS/Linux 为例)。设置方法可以参考以下示例:
   export GOPATH=/Users/username/go

你也可以将这个设置添加到你的 .bashrc.zshrc 文件中,以便每次启动终端时都自动设置。

  • 组织工程目录:在GOPATH目录下,你可以创建一个或多个工程目录。一般建议组织项目目录的方法是:
    使用src目录存放代码文件,
    使用bin目录存放可执行文件,
    使用pkg目录存放编译后的包文件。

    • 例如,在GOPATH目录下创建一个名为 my_project 的项目目录。
    • my_project 目录下创建 srcbinpkg 目录。
    • src 目录下创建你的项目源代码文件。
  1. 编写和构建代码:在你的项目目录下编写代码,并使用go buildgo run等命令来编译和运行你的代码。Go会自动到GOPATH设置的目录中查找依赖。

需要注意的是,GOPATH的设置是非常重要的,在构建和运行Go代码时,Go工具会根据GOPATH来查找代码和依赖。因此,确保正确设置GOPATH对于正确管理和使用你的Go项目是非常重要的。

另外,从Go1.11版本开始,Go引入了新的模块化管理系统go mod,并推荐使用模块(module)代替GOPATH,以更好地管理依赖关系。所以在使用较新版本的Go时,推荐使用go mod来管理项目。


Go 语言包管理02

在Go语言中,go mod是Go官方引入的模块化管理系统,用于管理项目的依赖关系。

以下是使用go mod的一般步骤:

  1. 初始化项目:在项目根目录下使用命令go mod init 初始化项目,并创建一个新的模块。为模块的名称,一般是项目的根路径。

  2. 添加依赖:使用命令go get 添加所需的依赖包。为依赖包的导入路径。go get命令会自动下载依赖包,并将其添加到项目的go.mod文件中。

  3. 更新依赖:使用命令go get -u更新依赖包。-u参数表示更新到最新版本。

  4. 移除依赖:使用命令go mod tidy移除项目未使用的依赖包。这个命令会根据项目的实际导入情况,自动删除go.mod文件中无用的依赖包。

  5. 查看依赖:可以使用命令go list -m all查看当前项目的依赖树,并显示每个依赖的版本信息。

  6. 构建项目:使用go build命令或其他相应的构建命令来构建项目。在使用go build命令的过程中,Go编译器会自动根据项目的go.mod文件来解析和下载相应的依赖包。

需要注意的是,使用go mod需要确保你的项目目录位于GOPATH之外。而且,建议在国内使用代理,可以加快依赖包下载的速度,如使用go env -w GOPROXY=https://goproxy.cn,direct设置代理。

以上是go mod的一般使用步骤,可以根据实际需要自行调整。


Go 语言基础语法

Go 标记

Go 程序可以由多个标记组成,可以是关键字,标识符,常量,字符串,符号。如以下 GO 语句由 6 个标记组成:

fmt.Println("Hello, World!")

6 个标记是(每行一个):

1. fmt
2. .
3. Println
4. (
5. "Hello, World!"
6. )

行分隔符

在 Go 程序中,一行代表一个语句结束。如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分。

fmt.Println("Hello, World!")
fmt.Println("csdn.net")

注释

// 单行注释

/*
 Author by 菜鸟教程
 我是多行注释
 */

标识符

标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(AZ和az)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。
以下是无效的标识符:

  • 1ab(以数字开头)
  • case(Go 语言的关键字)
  • a+b(运算符是不允许的)

字符串连接

Go 语言的字符串连接可以通过 + 实现。如fmt.Println("Google" + "Runoob")
输出GoogleRunoob

关键字、预定义标识符

下面列举了 Go 代码中会使用到的 25 个关键字或保留字:

关键字
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:

标识符
append bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int16 uint32
int32 int64 iota len make new nil panic uint64
print println real recover string true uint uint8 uintptr

程序一般由关键字、常量、变量、运算符、类型和函数组成。

程序中可能会使用到这些分隔符:括号 (),中括号 [] 和大括号 {}。

程序中可能会使用到这些标点符号:.,;:

Go 语言的空格

在 Go 语言中,空格通常用于分隔标识符、关键字、运算符和表达式,以提高代码的可读性。

在函数调用时,函数名和左边等号之间要使用空格,参数之间也要使用空格。

例如:

result := add(2, 3)

实际测试,不用空格也没见报错。

package main
import "fmt"
func main() {
	result:=add(2,3)
	fmt.Println(result)}
func add(num1,num2 int) int {
	return num1+num2}

格式化字符串

Go 语言中使用 fmt.Sprintf 或 fmt.Printf 格式化字符串并赋值给新串:
Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。
Printf 根据格式化参数生成格式化的字符串并写入标准输出。
例子

package main
import "fmt"

func main() {
   // %d 表示整型数字,%s 表示字符串
    var stockcode=123
    var enddate="2020-12-31"
    var url="Code=%d&endDate=%s"
    var target_url=fmt.Sprintf(url,stockcode,enddate)
    fmt.Println(target_url)}

输出

Code=123&endDate=2020-12-31

例子

package main
import "fmt"

func main() {
   // %d 表示整型数字,%s 表示字符串
    var stockcode=123
    var enddate="2020-12-31"
    var url="Code=%d&endDate=%s"
    fmt.Printf(url,stockcode,enddate)}

输出

Code=123&endDate=2020-12-31

更多参考

  • Go fmt.Sprintf 格式化字符串
  • Go fmt.Printf 格式化字符串

Go 语言数据类型

在 Go 编程语言中,数据类型用于声明函数和变量。

数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。

Go 语言按类别有以下几种数据类型:

序号 类型和描述
1 布尔型 布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。
2 数字类型 整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。
3 字符串类型: 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。
4 派生类型: 包括:(a) 指针类型(Pointer)(b) 数组类型© 结构化类型(struct)(d) Channel 类型(e) 函数类型(f) 切片类型(g) 接口类型(interface)(h) Map 类型

数字类型

Go 也有基于架构的类型,例如:int、uint 和 uintptr。

序号 类型和描述
1 uint8 无符号 8 位整型 (0 到 255)
2 uint16 无符号 16 位整型 (0 到 65535)
3 uint32 无符号 32 位整型 (0 到 4294967295)
4 uint64 无符号 64 位整型 (0 到 18446744073709551615)
5 int8 有符号 8 位整型 (-128 到 127)
6 int16 有符号 16 位整型 (-32768 到 32767)
7 int32 有符号 32 位整型 (-2147483648 到 2147483647)
8 int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)

浮点型

序号 类型和描述
1 float32 IEEE-754 32位浮点型数
2 float64 IEEE-754 64位浮点型数
3 complex64 32 位实数和虚数
4 complex128 64 位实数和虚数

其他数字类型

以下列出了其他更多的数字类型:

序号 类型和描述
1 byte 类似 uint8
2 rune 类似 int32
3 uint 32 或 64 位
4 int 与 uint 一样大小
5 uintptr 无符号整型,用于存放一个指针

Go 语言变量

变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。

变量可以通过变量名访问。

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

声明变量的一般形式是使用 var 关键字:

var identifier type

可以一次声明多个变量:

var identifier1, identifier2 type

例如

package main
import "fmt"
func main() {
    var a string = "csdn"
    fmt.Println(a)

    var b, c int = 1, 2
    fmt.Println(b, c)
}

输出

csdn
1 2

变量声明

第一种,指定变量类型,如果没有初始化,则变量默认为零值。

var v_name v_type
v_name = value

第二种,根据值自行判定变量类型。

var v_name = value

第三种,如果变量已经使用 var 声明过了,再使用 := 声明变量,就产生编译错误,格式:

v_name := value

放在一起对比
golang学习笔记——基础01_第2张图片
第一种变量声明,就是仅仅只声明变量,用到var关键字。如果没有初始化,则变量默认为零值(零值就是变量没有做初始化时系统默认设置的值)。
第二种,让系统自行判定变量类型,用到var关键字。
第三种,不用到var关键字,特别之处在于它用:=冒号等于号的组合来声名变量。

零值

零值就是变量没有做初始化时系统默认设置的值.

  • 数值类型(包括complex64/128)为 0

  • 布尔类型为 false

  • 字符串为 “”(空字符串)

  • 以下几种类型为 nil

 var a *int
 var a []int
 var a map[string] int
 var a chan int
 var a func(string) int
 var a error // error 是接口

多变量声明

//---001---
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3

//---002---
var vname1, vname2, vname3 = v1, v2, v3 // 和 python 很像,不需要显示声明类型,自动推断

//---003---
vname1, vname2, vname3 := v1, v2, v3 // 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误


//---004---
// 这种因式分解关键字的写法一般用于声明全局变量
var (
    vname1 v_type1
    vname2 v_type2
)

例子

package main
import "fmt"

var x, y int
var (	// 这种因式分解关键字的写法一般用于声明全局变量
	a int
	b bool
)

var c, d int = 1, 2
var e, f = 123, "hello"

//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"

func main(){
	g, h := 123, "hello"
	fmt.Println(x, y)
	fmt.Println(a, b)
	fmt.Println(c, d)
	fmt.Println(e, f, g, h)
}

输出

0 0
0 false
1 2
123 hello 123 hello

值类型和引用类型

在Go语言中,值类型(value types)和引用类型(reference types)是用来表示变量的两种不同的数据类型。

值类型是直接存储变量的值的数据类型。当将一个值类型的变量赋给另一个变量时,会将原始变量的值复制给新变量,两个变量之间是完全独立的。常见的值类型包括整型、浮点型、布尔型、字符串、数组和结构体。

例如:

a := 10
b := a
b = 20
fmt.Println(a) // 输出:10
fmt.Println(b) // 输出:20

引用类型是存储变量的指针的数据类型。当将一个引用类型的变量赋给另一个变量时,实际上是将指向数据的指针复制给新变量,两个变量之间指向的是同一个数据。常见的引用类型包括切片、映射、通道和函数。

例如:

x := []int{1, 2, 3}
y := x
y[0] = 4
fmt.Println(x) // 输出:[4, 2, 3]
fmt.Println(y) // 输出:[4, 2, 3]

需要注意的是,虽然通过引用类型可以实现变量之间的共享数据,但是在并发程序中,可能需要使用互斥锁等机制来保护共享数据,以避免竞态条件和数据竞争的问题。

简短形式

001、简短形式可以自动推断变量的类型

a := 50 或 b := false

a 和 b 的类型(int 和 bool)将由编译器自动推断。

002、不可以再次对于相同名称的变量使用初始化声明

package main
import "fmt"
func main(){
	a := 50
    // a := 20 //no new variables on left side of :=
	a = 20 //但是 a = 20 是可以的,因为这是给相同的变量赋予一个新的值
}

003、不可以在定义变量 a 之前使用它
004、声明了一个局部变量却没有在相同的代码块中使用它

package main

import "fmt"

func main() {
   var a string = "abc"
   fmt.Println("hello, world")
}

报错unexpected fmt at end of statement
应该改为fmt.Println("hello, world", a)

005、全局变量是允许只声明不使用。 同一类型的多个变量可以声明在同一行

var a, b, c int

006、多变量可以在同一行进行赋值

var a, b int
var c string
a, b, c = 5, 7, "abc"

007、空白标识符
如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a,两个变量的类型必须是相同。

空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。

空白标识符在函数返回值时的使用

package main

import "fmt"

func main() {
  _,numb,strs := numbers() //只获取函数返回值的后两个
  fmt.Println(numb,strs)
}

//一个可以返回多个值的函数
func numbers()(int,int,string){
  a , b , c := 1 , 2 , "str"
  return a,b,c
}

输出2 str


Go 语言常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量的定义格式:

const identifier [type] = value

你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

  • 显式类型定义: const b string = "abc"
  • 隐式类型定义: const b = "abc"

多个相同类型的声明可以简写为:

const c_name1, c_name2 = value1, value2

以下实例演示了常量的应用:

package main

import "fmt"

func main() {
   const LENGTH int = 10
   const WIDTH int = 5   
   var area int
   const a, b, c = 1, false, "str" //多重赋值

   area = LENGTH * WIDTH
   fmt.Printf("面积为 : %d", area)
   println()
   println(a, b, c)   
}

​ 以上实例运行结果为:

面积为 : 50
1 false str

常量还可以用作枚举:

const (
    Unknown = 0
    Female = 1
    Male = 2
)

数字 0、1 和 2 分别代表未知性别、女性和男性。

常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:

package main

import "unsafe"
const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(a)
)

func main(){
    println(a, b, c)
}

以上实例运行结果为:

abc 3 16

iota

iota是go语言的常量计数器,只能在常量的表达式中使用。

iota在const关键字出现时将被重置为0。const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。

举个例子:

    const (
            n1 = iota //0
            n2        //1
            n3        //2
            n4        //3
        )

几个常见的iota示例:

使用_跳过某些值

    const (
            n1 = iota //0
            n2        //1
            _
            n4        //3
        )

iota声明中间插队

    const (
            n1 = iota //0
            n2 = 100  //100
            n3 = iota //2
            n4        //3
        )
    const n5 = iota //0

定义数量级 (这里的<<表示左移操作,1<<10表示将1的二进制表示向左移10位,也就是由1变成了10000000000,也就是十进制的1024。同理2<<2表示将2的二进制表示向左移2位,也就是由10变成了1000,也就是十进制的8。)

    const (
            _  = iota
            KB = 1 << (10 * iota)
            MB = 1 << (10 * iota)
            GB = 1 << (10 * iota)
            TB = 1 << (10 * iota)
            PB = 1 << (10 * iota)
        )

多个iota定义在一行

    const (
            a, b = iota + 1, iota + 2 //1,2
            c, d                      //2,3
            e, f                      //3,4
        )

参考资料

go语言教程
go的包管理
go在线工具
一文带你了解 Go mod
Go语言GOPATH详解(Go语言工作目录)
GOPATH的使用方式
go系列-值类型与引用类型

你可能感兴趣的:(golang从入门到入门,golang,学习,笔记)