Go 语言入门指南:基础语法和常用特性解析-上篇| 豆包MarsCode AI 刷题

70 阅读8分钟

本文将从学习掘金Go语言基础课程入手,总结Go 语言入门指南:基础语法和常用特性解析。

Go语言,这个由谷歌开发的编程语言,自诞生以来就因其强大的背景和卓越的性能吸引了众多开发者的目光。Go语言的创造者包括计算机科学领域的三位杰出人物:Rob Pike、Ken Thompson和Robert Griesemer。这门年轻的语言在短短十年间迅速崛起,已经成为许多重要应用的基础,例如在容器技术领域占据领导地位的Docker就是用Go语言开发的。

在全球范围内,Go语言的应用越来越广泛,国内的许多技术团队也开始大规模采用Go语言。最近,HackerRank对超过70000名来自100多个国家的开发者进行了一项技能调查。结果显示,在2019年,Go语言以37.2%的比例高居程序员最想学习的编程语言榜首,紧随其后的是Kotlin和Python。

谷歌的前员工Jake Wilson认为,Go语言相较于Python有许多优势,可以在多种场景下替代Python。他已经在多个项目中用Go语言取代了Python。Go语言的快速发展和广泛应用,不仅得益于其高效的性能和简洁的语法,还因为它在并发处理、网络编程和系统编程方面表现出色。随着越来越多的企业和开发者认识到Go语言的优势,它在编程世界中的地位也在不断提升。

1.hello:要导入fmt包 以使用println 不需要句末写分号


import (
	"fmt"
)

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

2.var变量 有很多创建变量的方式如下,但是最常用的也是最好用的就是直接冒号等于号,但是这个只能在函数体内,而不能用它来创建全局变量。可以指定变量类型,也可以直接让其推断。


import (
	"fmt"
	"math"
)

func main() {

	var a = "initial"
	var b, c int = 1, 2
	var d = true
	var e float64
	f := float32(e)
	g := a + "foo"
	fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
	fmt.Println(g)                // initialapple

	const s string = "constant"
	const h = 500000000
	const i = 3e20 / h
	fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}

3.for循环 和c不同的是 不需要小括号 而且也可以直接for 当while使用 go里面没有while循环、do while循环,只有唯一的一种for循环,可以用break或者continue来跳出或者继续循环。


import "fmt"

func main() {

	i := 1
	for {
		fmt.Println("loop")
		break
	}
	for j := 7; j < 9; j++ {
		fmt.Println(j)
	}

	for n := 0; n < 5; n++ {
		if n%2 == 0 {
			continue
		}
		fmt.Println(n)
	}
	for i <= 3 {
		fmt.Println(i)
		i = i + 1
	}
}

4.if if后面必须接大括号,不能像C或者C++一样,直接把f里面的语句同一行。

  • 在第三个if语句中,使用了简短变量声明num := 9来声明一个变量num并赋值为9。这种声明方式是Go语言特有的,可以在任何地方使用,而不仅仅是在函数的开始处。

  • 多重条件判断:第三个if语句中包含了else ifelse,用于对num的值进行多重条件判断。

    • 如果num小于0,会打印出num是负数。
    • 如果num小于10,会打印出num是一位数。
    • 否则,会打印出num是多位数。

import "fmt"

func main() {

	if 7%2 == 0 {
		fmt.Println("7 is even")
	} else {
		fmt.Println("7 is odd")
	}

	if 8%4 == 0 {
		fmt.Println("8 is divisible by 4")
	}

	if num := 9; num < 0 {
		fmt.Println(num, "is negative")
	} else if num < 10 {
		fmt.Println(num, "has 1 digit")
	} else {
		fmt.Println(num, "has multiple digits")
	}
}

5.switch 第一个switch语句根据变量a的值来决定执行哪个case分支。在这个例子中,a的值为2,因此会执行case 2分支,并打印出"two"。 - case后面可以跟一个或多个值,如果表达式的值与这些值中的任何一个匹配,就会执行对应的代码块。在这个例子中,case 4, 5表示如果a的值为4或5,都会执行同一个代码块。

  • default分支:如果没有case匹配,就会执行default分支。在这个例子中,由于a的值为2,所以不会执行default分支。

import (
	"fmt"
	"time"
)

func main() {

	a := 2
	switch a {
	case 1:
		fmt.Println("one")
	case 2:
		fmt.Println("two")
	case 3:
		fmt.Println("three")
	case 4, 5:
		fmt.Println("four or five")
	default:
		fmt.Println("other")
	}

	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("It's before noon")
	default:
		fmt.Println("It's after noon")
	}
}

6.array var a [5]int声明了一个长度为5的整型数组a,此时数组中的元素都被自动初始化为int类型的零值,即0b := [5]int{1, 2, 3, 4, 5}使用数组字面量声明并初始化了一个长度为5的整型数组b,数组中的元素依次为1, 2, 3, 4, 5var twoD [2][3]int声明了一个二维数组twoD,它包含2个长度为3的整型数组。


import "fmt"

func main() {

	var a [5]int
	a[4] = 100
	fmt.Println("get:", a[2])
	fmt.Println("len:", len(a))

	b := [5]int{1, 2, 3, 4, 5}
	fmt.Println(b)

	var twoD [2][3]int
	for i := 0; i < 2; i++ {
		for j := 0; j < 3; j++ {
			twoD[i][j] = i + j
		}
	}
	fmt.Println("2d: ", twoD)
}

7.slice 切片类似于array,也可以用下标访问。但是可以自动扩容。
常用创建:slice := make([]int, 5, 10)当然,容量可以不传,默认和长度相等。

  • s := make([]string, 3)创建了一个长度为3的字符串切片s,并初始化为默认的空字符串""
  • 接着,通过索引赋值的方式,将s的前三个元素分别设置为"a""b""c"
  • s = append(s, "d")向切片s追加一个元素"d"
  • s = append(s, "e", "f")向切片s追加两个元素"e""f"fmt.Println(s[2:5])打印切片s从索引2到索引4(不包含5)的子切片,输出为["c", "d", "e"]。(这是左闭右开的区间)
  • good := []string{"g", "o", "o", "d"}使用切片字面量创建并初始化了一个字符串切片good,包含元素"g""o""o""d"

import "fmt"

func main() {

	s := make([]string, 3)
	s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	fmt.Println("get:", s[2])   // c
	fmt.Println("len:", len(s)) // 3

	s = append(s, "d")
	s = append(s, "e", "f")
	fmt.Println(s) // [a b c d e f]

	c := make([]string, len(s))
	copy(c, s)
	fmt.Println(c) // [a b c d e f]

	fmt.Println(s[2:5]) // [c d e]
	fmt.Println(s[:5])  // [a b c d e]
	fmt.Println(s[2:])  // [c d e f]

	good := []string{"g", "o", "o", "d"}
	fmt.Println(good) // [g o o d]
}

8.map m := make(map[string]int)创建了一个字符串到整数的映射mm["one"] = 1m["two"] = 2将键"one""two"分别映射到值12。- fmt.Println(m["one"])访问并打印映射m中键"one"对应的值,输出为1fmt.Println(m["unknow"])尝试访问不存在的键"unknow",由于映射中不存在该键,Go语言会自动为其赋值为该类型的零值,即0


import "fmt"

func main() {
	m := make(map[string]int)
	m["one"] = 1
	m["two"] = 2
	fmt.Println(m)           // map[one:1 two:2]
	fmt.Println(len(m))      // 2
	fmt.Println(m["one"])    // 1
	fmt.Println(m["unknow"]) // 0

	r, ok := m["unknow"]
	fmt.Println(r, ok) // 0 false

	delete(m, "one")

	m2 := map[string]int{"one": 1, "two": 2}
	var m3 = map[string]int{"one": 1, "two": 2}
	fmt.Println(m2, m3)
}

9-range Go语言中遍历数组和映射的基本操作,包括使用range关键字来同时获取索引和值,以及只获取键或值。这种遍历方式是Go语言中处理集合类型数据时常用的方法。

  • nums := []int{2, 3, 4}创建了一个包含三个整数的切片nums
  • sum := 0声明了一个变量sum用于累加数组中的元素。
  • for i, num := range nums是一个for循环,使用range关键字遍历数组numsi是元素的索引,num是元素的值。
  • 在循环体内,sum += num将当前元素的值累加到sum变量中。
  • 如果num等于2,则打印该元素的索引i和值num

import "fmt"

func main() {
	nums := []int{2, 3, 4}
	sum := 0
	for i, num := range nums {
		sum += num
		if num == 2 {
			fmt.Println("index:", i, "num:", num) // index: 0 num: 2
		}
	}
	fmt.Println(sum) // 9

	m := map[string]string{"a": "A", "b": "B"}
	for k, v := range m {
		fmt.Println(k, v) // b 8; a A
	}
	for k := range m {
		fmt.Println("key", k) // key a; key b
	}
}

10.func

  • add(a int, b int) int定义了一个名为add的函数,它接受两个整数参数ab,并返回它们的和。
  • add2(a, b int) int定义了一个名为add2的函数,它同样接受两个整数参数ab,并返回它们的和。这个函数的参数列表没有指定参数名,这在Go语言中是允许的,此时参数名在函数体内部不可用,但可以调用函数。
    • res := add(1, 2)调用add函数,传入参数12,并将返回值赋给变量res
  • fmt.Println(res)打印变量res的值,输出为3
  • exists(m map[string]string, k string) (v string, ok bool)定义了一个名为exists的函数,它接受一个字符串映射m和一个字符串键k作为参数,并返回两个值:v是映射中键k对应的值,ok是一个布尔值,表示键k是否存在于映射m中。

import "fmt"

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

func add2(a, b int) int {
	return a + b
}

func exists(m map[string]string, k string) (v string, ok bool) {
	v, ok = m[k]
	return v, ok
}

func main() {
	res := add(1, 2)
	fmt.Println(res) // 3

	v, ok := exists(map[string]string{"a": "A"}, "a")
	fmt.Println(v, ok) // A True
}