GoLang 语言基础

基础语法

变量声明

go 复制代码
package main

func main() {
    // 变量声明(类型推导)
    name := "jack"
    age := 10

    // 显式声明
    var pi float64 = 3.14
    fmt.Println(name, age, pi)
}

以下有一些常见的语法规则:

1、在 GoLang 中,:= 只能在函数内用,包级需要使用 var 显式声明。

2、未使用的变量 / import 会报错(Go 强迫写干净的代码)。

循环与判断

go 复制代码
package main

func main() {
    age := 10
    
    // if 内的条件语句不需要使用 () 包围
    if age > 5 {
        // ...
    }

    // Go 只有 for 循环,没有 while 以及 do-while
    for i := 0; i < 3; i++ {
        // ...
    }

    // 类似 while 的写法
    n := 3
    for n < 3 {
        n++
    }
}

数组与切片

基础语法:

  • 数组:[N]T
  • 切片:[]T

在 Go 中,数组的大小是固定的,不可扩容,且属于值语义。

go 复制代码
package main

func main() {
    // 声明数组
    nums := [3]int{1, 2, 3}

    // 自动推导长度
    nums2 := [...]int{1, 2, 3, 4}

    fmt.Println(nums) // [1 2 3]
    fmt.Println(nums2) // [1 2 3 4]

    // 值语义
    a := [3]int {1, 1, 1}
    b := a;

    b[0] = 100;

    fmt.Println(a)  // [1 1 1]
    fmt.Println(b)  // [100 1 1]
}

切片的大小是可变的,可以通过 append 增加元素,属于引用语义。

go 复制代码
package main

import "fmt"

func main() {

	// 声明切片
	a := []int{1, 2, 3}

	b := a
	b[0] = 100

	// 引用语义
	fmt.Println(a) // [100 2 3]
	fmt.Println(b) // [100 2 3]

	b = append(b, 4)
	b = append(b, 5, 6, 7)

	fmt.Println(a) // [100 2 3]
	fmt.Println(b) // [100 2 3 4 5]
}

可以通过 make 创建切片,并设置长度和容量。

go 复制代码
package main

func main() {
    // 可以通过 make 创建切片并设置 capacity
    c := make([]int, 3, 5)

    fmt.Println(c) // [0 0 0]
    fmt.Println(len(c), cap(c)) // 3 5
}

Map

基础语法:

  • map[key]value

Map 用来表示映射关系,在 Go 中,Map 属于内置的数据类型。

go 复制代码
package main

func main() {
    
    // 字面量初始化
    // 每个记录后面必须以 "," 结尾,哪怕是最后一项
    scores := map[string]int {
        "小明": 90,
        "小玉": 99,
    }

    fmt.Println(scores["小明"])

    // 判断 Map 中是否存在某个元素
    score, ok := scores["小青"]
    if !ok {
        fmt.Println("小青不存在")
    }

    // 增加元素
    scores["小青"] = 100

    // 删除元素(删除不存在的不会报错)
    delete(scores, "小青")

    // 遍历 Map
    for k, v := range scores {
        fmt.Println(k, v)
    }
}

函数、结构体与指针

函数

GoLang 的函数支持多返回值,函数可以作为参数传递,没有默认参数,没有函数重载。

go 复制代码
// 定义一个最基本的函数
func 函数名(参数) 返回值类型 {
    
}

// add 函数
func add(a int, b int) int {
    return a + b
}

// 参数类型相同可以简写
func add(a, b int) int {
    return a + b;
}

// Go 支持多返回值(这是很常用的特性)
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为0")
    }
    return a / b, nil
}

指针

GoLang 中也有指针,但是比 C++ / C 的简单很多,不需要自己手动管理内存。

bash 复制代码
x := 10
p := &x  // p 是指向 x 的指针,& 进行取地址

*p = 20

fmt.Println(x) // 20

结构体

GoLang 没有 class,用 struct 代替。

go 复制代码
// 定义结构体
type Server struct {
    Name string
    IP   string
    Port string
    Running bool
}

// 创建实例
s := Server{
    Name:    "web-01",
    IP:      "192.168.1.1",
    Port:    8080,
    Running: true,
}

// 访问字段
fmt.Println(s.Name, s.Port)

方法是绑在结构体上的函数,GoLang 拥有两个新增的概念

  • 值接收者
  • 指针接收者

两个接收者的区别在于其定义的函数能不能修改结构体内的字段。

go 复制代码
// 值接收者(不修改原结构体)
func (s Server) Status() string {
    if s.Running {
        return s.Name + " is running"
    }
    return s.Name + " is stopped"
}

// 指针接收者(可以修改结构体)
func (s *Server) Stop() {
    s.Running = false
}

// 调用
s.Stop()
fmt.Println(s.Status())  // web-01 is stopped

需要修改结构体字段时用指针接收者 *Server,只读用值接收者 Server

相关推荐
两年半的个人练习生^_^1 小时前
JMM 进阶:彻底理解 synchronized 实现原理
java·开发语言
小白不白1111 小时前
Invoke的用法
开发语言·人工智能·数码相机·计算机视觉·c#
踏着七彩祥云的小丑1 小时前
Go学习第4天:条件、循环语句+函数
学习·golang·go
techdashen1 小时前
What is maintenance, anyway?
开发语言·后端·rust
万法若空1 小时前
C/C++基本类型表示范围
c语言·开发语言·c++
yijianace1 小时前
Python爬虫实战:BooksToScrape 多线程爬取与图片下载
开发语言·爬虫·python
凡人叶枫1 小时前
Effective C++ 条款15:在资源管理类中提供对原始资源的访问
linux·开发语言·c++·stm32·单片机
swordbob1 小时前
Spring Boot 2.0 改 CGLIB 后,接口实现是否有影响
java·开发语言·spring