Go语言基础语法 | 豆包MarsCode AI 刷题

60 阅读8分钟

Go语言基础语法

输出hello world

 package main        //包名
 ​
 import (
     "fmt"          //导入标准库的FMT包,主要用于输入输出、格式化字符串
 )
 ​
 func main() {
     fmt.Println("hello world")    //调用Println方法输出
 }

变量类型

 package main
 ​
 import (    //导入fmt和math包
     "fmt"
     "math"
 )
 ​
 func main() {
 ​
     var a = "initial"          //自动推导变量类型
 ​
     var b, c int = 1, 2        //必要时也可以写出类型
 ​
     var d = true
 ​
     var e float64             //声明64位的float类型的变量e,未进行赋值,用默认值输出
 ​
     f := float32(e)           //另一种声明方式 ":=",将e转化为32位float类型,赋值给f
 ​
     g := a + "foo"            //字符串拼接
     fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
     fmt.Println(g)                // initialfoo
 ​
     const s string = "constant"     //声明常量
     const h = 500000000
     const i = 3e20 / h
     fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
 }
 ​

运行结果

屏幕截图 2024-11-03 161056.png

分支语句

if-else语句

 package main
 ​
 import "fmt"
 ​
 func main() {
 ​
     if 7%2 == 0 {                  //if后面的括号可加可不加
         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")
     }
 }
 ​

switch语句

 package main
 ​
 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:              //case内容可以是字符串、结构体等其他类型
         fmt.Println("It's before noon")
     default:
         fmt.Println("It's after noon")
     }
 }

运行结果

屏幕截图 2024-11-03 162102.png

循环

go语言只有for循环

 package main
 ​
 import "fmt"
 ​
 func main() {
 ​
     i := 1         //声明变量i等于1
     for {                             //三个条件都省略了的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
     }
 }
 ​

运行结果

屏幕截图 2024-11-03 161829.png

数组

 package main
 ​
 import "fmt"
 ​
 func main() {
 ​
     var a [5]int           //定义包含5个元素的整数数组a
     a[4] = 100            //令第五个元素为100
     fmt.Println("get:", a[2])    //默认值为0
     fmt.Println("len:", len(a))  //返回数组长度5
 ​
     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)
 }

运行结果

屏幕截图 2024-11-03 204522.png

在真实业务代码里很少用数组,因为其长度是固定的,使用更多的是切片。

切片

 package main
 ​
 import "fmt"
 ​
 func main() {
 ​
     s := make([]string, 3)                 //使用make创建一个长度为3的String切片s
     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后面添加一个元素d,得到的切片覆盖原切片s
     s = append(s, "e", "f")               //追加两个元素
     fmt.Println(s) // [a b c d e f]
 ​
     c := make([]string, len(s))
     copy(c, s)                            //把s赋值给c
     fmt.Println(c) // [a b c d e f]
 ​
     fmt.Println(s[2:5]) // 取第2到第4个元素:[c d e]
     fmt.Println(s[:5])  // [a b c d e]
     fmt.Println(s[2:])  // [c d e f]
 }
 ​

Map

 package main
 ​
 import "fmt"
 ​
 func main() {
     m := make(map[string]int)         //使用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)      //map[one:1 two:2] map[one:1 two:2]
 }

range

package main

import "fmt"

func main() {
	nums := []int{2, 3, 4}
	for i, num := range nums {          //使用range遍历数组nums,返回索引i和元素num
        fmt.Println("index:", i, "num:", num)   
	}  

	m := map[string]string{"a": "A", "b": "B"}   //使用range遍历map
	for k, v := range m {       //返回键和值
		fmt.Println(k, v) 
	}
	for k := range m {       //返回键
		fmt.Println("key", k) 
	}
}

运行结果

屏幕截图 2024-11-03 211535.png

函数

package main

import "fmt"

func add(a int, b int) int {   //接收int类型a、b,返回int类型
	return a + b
}	

func exists(m map[string]string, k string) (v string, ok bool) {   //第一个括号是接受的参数,第二个括号是返回值
	v, ok = m[k]   //第二个返回的参数ok是bool类型,如果键存在则为true,不存在则为false
	return v, ok
}

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

	v, ok := exists(map[string]string{"a": "A"}, "a")
	if ok {
    	fmt.Println("Key exists:", v)
    } else {
        fmt.Println("Key does not exist")
    }
}

指针

package main

import "fmt"

func add2(n int) {   //没有修改实参n的值
	n += 2
}

func add2ptr(n *int) {   //使用指针,修改了实参的值,*n表示传入的地址n对应的值
	*n += 2
}

func main() {
	n := 5
	add2(n)        //传入n
	fmt.Println(n) // 5
	add2ptr(&n)    //&n表示传入n的地址
	fmt.Println(n) // 7
}

结构体

package main

import "fmt"

//声明结构体
type user struct {
	name     string
	password string
}

func checkPassword(u user, password string) bool {
	return u.password == password
}
//使用指针可以避免不必要的复制,并且可以修改原始对象,在这个例子中使用值传递或指针都可以
func checkPassword2(u *user, password string) bool {
	return u.password == password
}

//使用指针传递修改原结构体的元素值
func (u *user) resetPassword(password string) {
	u.password = password
}

func main() {
	a := user{name: "wang", password: "1024"}   //给结构体赋值,以下是其他等价的赋值方法
	b := user{"wang", "1024"}
	c := user{name: "wang"}
	c.password = "1024"
	var d user
	d.name = "wang"
	d.password = "1024"

	fmt.Println(a, b, c, d)                 // {wang 1024} {wang 1024} {wang 1024} {wang 1024}
	fmt.Println(checkPassword(a, "haha"))   // false
	fmt.Println(checkPassword2(&a, "haha")) // false
    
    a.resetPassword("2048")
	fmt.Println(a.checkPassword("2048")) // true
}

异常

go语言中的异常是一个接口类型,通常在函数的返回值中包含。当函数执行过程中出现错误时,它会返回一个非nil的错误值。

package main

import (
	"errors"
	"fmt"
)

// 定义一个简单的函数,模拟除法操作
func divide(a, b int) (int, error) {
	if b == 0 {
		// 如果除数为0,返回错误
		return 0, errors.New("除数不能为0")
	}
	return a / b, nil    //没有异常的情况下,返回nil
}

func main() {
	// 调用divide函数,并处理可能出现的错误
	result, err := divide(10, 2)
	if err != nil {
		// 如果出现错误,打印错误信息
		fmt.Println("错误:", err)
	} else {
		// 如果没有错误,打印结果
		fmt.Println("结果:", result)
	}

	// 故意调用一个会导致错误的函数
	result, err = divide(10, 0)
	if err != nil {
		fmt.Println("错误:", err)
	} else {
		fmt.Println("结果:", result)
	}
}

运行结果

屏幕截图 2024-11-03 225821.png

String类型

package main

import (
	"fmt"
	"strings"
)

func main() {
	a := "hello"
	fmt.Println(strings.Contains(a, "ll"))                // 判断是否包含:true
	fmt.Println(strings.Count(a, "l"))                    // 计算字符出现的次数:2
	fmt.Println(strings.HasPrefix(a, "he"))               // 判断是否以该字符串开头:true
	fmt.Println(strings.HasSuffix(a, "llo"))              // 判断是否以该字符串结尾:true
	fmt.Println(strings.Index(a, "ll"))                   // 获取字符在字符串中的索引,没有则返回-1:2
	fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // 在字符串中添加字符:he-llo
	fmt.Println(strings.Repeat(a, 2))                     // 重复字符串:hellohello
	fmt.Println(strings.Replace(a, "e", "E", -1))         // 将第二个参数替换成第三个参数,第四个参数表示要替换的实例个数,-1表示全部替换:hEllo
	fmt.Println(strings.Split("a-b-c", "-"))              // 去掉某个字符:[a b c]
	fmt.Println(strings.ToLower(a))                       // 转小写:hello
	fmt.Println(strings.ToUpper(a))                       // 转大写:HELLO
	fmt.Println(len(a))                                   // 返回字符串长度:5
	b := "你好"
	fmt.Println(len(b)) // 6
}

fmt库

package main

import "fmt"

type point struct {
	x, y int
}

func main() {
	s := "hello"
	n := 123
	p := point{1, 2}   //初始化结构体point实例p
	//Println用于输出简单的参数,用空格隔开,然后换行
    fmt.Println(s, n) // hello 123
	fmt.Println(p)    // {1 2}

    //Printf用于根据指定的格式字符串输出参数
	fmt.Printf("s=%v\n", s)  // s=hello
	fmt.Printf("n=%v\n", n)  // n=123
	fmt.Printf("p=%v\n", p)  // p={1 2}
	fmt.Printf("p=%+v\n", p) // 输出结构体 p 的值,并包含字段名,即 {x:1 y:2}
	fmt.Printf("p=%#v\n", p) // 输出结构体 p 的Go语法表示,包括类型和字段名,即 main.point{x:1, y:2}。

	f := 3.141592653
	fmt.Println(f)          // 3.141592653
	fmt.Printf("%.2f\n", f) // 保留小数点后两位:3.14
}

Json库

package main

import (
	"encoding/json"
	"fmt"
)

type userInfo struct {
	Name  string
	Age   int `json:"age"`
	Hobby []string
}

func main() {
	a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
	buf, err := json.Marshal(a)   //将Go语言中的数据结构编码为JSON格式的字节切片
	if err != nil {
		panic(err)      //如果出现异常,打印异常信息并退出程序
	}
	fmt.Println(buf)         // [123 34 78 97...]
	fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}

	buf, err = json.MarshalIndent(a, "", "\t")   //将Go语言中的数据结构编码为格式化的JSON字符串
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))

	var b userInfo
	err = json.Unmarshal(buf, &b)     //用于将JSON格式的数据解码为Go语言中的数据结构
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}

运行结果

屏幕截图 2024-11-03 232811.png

time库

package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()     //获取现在的时间
	fmt.Println(now) 
    
	t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
	t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
	fmt.Println(t)                                                  // 2022-03-27 01:25:36 +0000 UTC
	fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
	fmt.Println(t.Format("2006-01-02 15:04:05"))                    // 2022-03-27 01:25:36
    
	diff := t2.Sub(t)                           //求时间差值
	fmt.Println(diff)                           // 1h5m0s
	fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
    
	t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")       //time.Parse 函数用于解析一个格式化的时间字符串,并将其转换为 time.Time 对象。第一个参数是格式,第二个参数才是需要解析的时间字符串
	if err != nil {
		panic(err)
	}
	fmt.Println(t3 == t)    // true
	fmt.Println(now.Unix()) //用于获取当前时间的Unix时间戳(自1970年1月1日以来的秒数)
}

运行结果

屏幕截图 2024-11-03 233525.png

数字解析

package main

import (
	"fmt"
	"strconv"
)

func main() {
	f, _ := strconv.ParseFloat("1.234", 64)   //用于将字符串解析为浮点数,第二个参数表示解析为float64 类型
	fmt.Println(f) // 1.234

	n, _ := strconv.ParseInt("111", 10, 64)   //用于将字符串解析为整数,10进制的64int类型
	fmt.Println(n) // 111

	n, _ = strconv.ParseInt("0x1000", 0, 64)  //当参数为0时,ParseInt会自动检测字符串的进制基数。"0x1000" 会被识别为十六进制
	fmt.Println(n) // 4096

	n2, _ := strconv.Atoi("123")     //strconv.Atoi 函数是一个简化的版本,用于将字符串解析为 int 类型的整数
	fmt.Println(n2) // 123

	n2, err := strconv.Atoi("AAA")
	fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}

进程信息

package main

import (
	"fmt"
	"os"
	"os/exec"
)

func main() {
	// go run example/20-env/main.go a b c d
	fmt.Println(os.Args)           // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d]
	fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
	fmt.Println(os.Setenv("AA", "BB"))

	buf, err := exec.Command("findstr", "127.0.0.1", "/etc/hosts").CombinedOutput()
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf)) // 127.0.0.1       localhost
}