Go基础语法

golang基础
创建于:2020年02月12日 更新于:2021年03月01日

Go语言以“包”作为管理单位,每个 Go 源文件必须声明它所属的包,所以我们会看到每个 Go 源文件的开头都是一个 package 声明

package main    // 声明 main 包,main 包是 Go 语言程序的入口包,一个 Go 语言程序必须有且仅有一个 main 包。如果一个程序没有 main 包,那么编译时将会出错,无法生成可执行文件。

import "fmt"       // 导入 fmt 包,导入的包中不能含有代码中没有使用到的包,否则Go编译器会报编译错误

func main() {   // 声明 main 主函数,main 函数只能声明在 main 包中,不能声明在其他包中,并且,一个 main 包中也必须有且仅有一个 main 函数。Go语言函数的左大括号{必须和函数名称在同一行,否则会报错。
    fmt.Println("Hello World!") // 打印 Hello World!
}

Go 语言基本数据类型

  1. 布尔型,默认为 false
    • bool 布尔型的值只可以是 true 或者 false
  2. 字符串类型,默认值为空字符串,使用双引号或反引号定义。字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容
    • string 编码统一为 UTF-8 编码标识 Unicode 文本
  3. 整型,默认值为0

    • uint8:无符号8位整型(0 - 255)
    • uint16:无符号16位整型(0 - 65535)
    • uint32:无符号32位整型(0 - 4294967295)
    • uint64:无符号64位整型(0 - 18446744073709551615)
    • int8:有符号8位整型(-128 ~ 127)
    • int16:有符号16位整型(-32768 ~ 32767)
    • int32:有符号32位整型(-2147483648 ~ 2147483647)
    • int64:有符号64位整型(-9223372036854775808 ~ 9223372036854775807)
    • uintptr:无符号整型,用于存放一个指针
    • int:有符号32位或64位
    • uint:无符号32位或64位
    • byte:类似 uint8
    • rune:类似 int32
  4. 浮点型,默认为0,声明一个没有指定数据类型的浮点数时,默认为float64类型

    • float32:32位浮点数
    • float64:64位浮点数
    • complex64:32位实数和虚数
    • complex128:64位实数和虚数

大多数情况下,我们只需要 int 一种整型即可,它可以用于循环计数器(for 循环中控制循环次数的变量)、数组和切片的索引,以及任何通用目的的整型运算符,通常 int 类型的处理速度也是最快的。

byte 和 rune 可以表示字符类型

var b byte = 'a'
fmt.Println(b) // 97

Go语言中不允许将布尔型强制转换为整型,编译会报错

var n bool
fmt.Println(int(n))
// cannot convert n (type bool) to type int

变量的声明

使用 var 关键字(函数内外都可使用)

1. var a, b int
2. var a, b string = "hello", "world" // 字符串不能用单引号,可以不提供变量类型
3. var (
    a int,
    b string,
    c bool = true,
    d = "hi"
)
4. str := `this is another
string`

使用 := 方式声明(仅函数内部可用)
使用 := 声明变量不能提供数据类型

1. a := 1
2. a, b := 2, "hi" // 同时声明并赋值多个变量

Go语言中没有隐式转换,只能强制转换,const 定义常量没有指定数据类型时可以隐式的转换数据类型

package main

import "fmt"

func sum(a float32, b float32) float32{
    return a + b
}

func main(){
    // var m, n = 1.1, 2 // 报错
    const m, n = 1.1, 2 // 正常
    fmt.Println(sum(m, n))
}

常量

常量使用关键字 const 定义,用于存储不会改变的数据。
存储在常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
常量的定义格式:const identifier [type] = value,例如:const Pi = 3.14159

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

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

数字型的常量是没有大小和符号的,并且可以使用任何精度而不会导致溢出

并行赋值

const beef, two, c = "eat", 2, "veg"
const Monday, Tuesday, Wednesday, Thursday, Friday, Saturday = 1, 2, 3, 4, 5, 6
const (
    Monday, Tuesday, Wednesday = 1, 2, 3
    Thursday, Friday, Saturday = 4, 5, 6
)

指针

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用在变量名前面添加&操作符(前缀)来获取变量的内存地址(取地址操作)

package main

import "fmt"

func main(){
    str := "指针"
    fmt.Println(&str) // 0xc0000501f0
    fmt.Printf("%T", &str) // *string
}

当使用&操作符对普通变量进行取地址操作并得到变量的指针后,可以对指针使用*操作符,也就是指针取值

package main

import "fmt"

func main(){
    str := "PHP is the best language in the world!"

    ptr := &str

    value := *ptr

    // 打印ptr的类型
    fmt.Printf("ptr type: %T\n", ptr) // ptr type: *string

    // 打印ptr的指针地址
    fmt.Printf("address: %p\n", ptr) // address: 0xc0000661e0

    // 取值后的类型
    fmt.Printf("value type: %T\n", value) // value type: string

    // 指针取值后就是指向变量的值
    fmt.Printf("value: %s\n", value) //value: PHP is the best language in the world!
}

*操作符的根本意义就是操作指针指向的变量。当操作在右值时,就是获取指向变量的值,当操作在左值时,就是将值设置给指向的变量。

使用指针修改值

package main

import "fmt"

func swap(a, b *int) {
    *a, *b = *b, *a
}

func main(){
    a, b := 1, 2
    fmt.Println(a, b) // 1 2
    swap(&a, &b)
    fmt.Println(a, b) // 2 1
}

创建指针的另一种方法 — new()函数
Go语言还提供了另外一种方法来创建指针变量,方法如下:

str := new(string)
*str = "PHP is the best language in the world!"
fmt.Println(*str) // PHP is the best language in the world!

类型别名与类型定义

类型别名
类型别名规定:TypeAlias 只是 Type 的别名,本质上 TypeAlias 与 Type 是同一个类型,就像一个孩子小时候有小名、乳名,上学后用学名,英语老师又会给他起英文名,但这些名字都指的是他本人。
语法:type TypeAlias = Type

package main
import "fmt"

type IntAlias = int

func main() {
    var a, b IntAlias = 3, 4
    c := a + b
    fmt.Printf("c has the value: %d", c) // 输出:c has the value: 7
}

类型定义
type NewType Type

package main

import "fmt"

//类型定义
type NewInt int

//类型别名
type AliasInt = int

func main() {
    var a NewInt
    var b AliasInt

    fmt.Printf("type ocf a:%T\n", a) //type of a:main.NewInt
    fmt.Printf("type of b:%T\n", b) //type of b:int
}
// 区别:结果显示a的类型是main.NewInt,表示main包下定义的NewInt类型。b的类型是int。AliasInt类型只会在代码中存在,编译完成时并不会有AliasInt类型。