01-hello
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
package main:这一行声明了这个文件属于main包。在Go语言中,每个程序必须属于一个包,而main包是一个特殊的包,它定义了一个可执行程序的入口点。import "fmt":这一行导入了fmt包,fmt包是Go语言标准库中的一个包,它提供了格式化输入和输出的函数,例如Println函数。func main() {...}:这是main函数的定义,main函数是程序的入口点,当你运行这个程序时,程序会从这里开始执行。fmt.Println("hello world"):这一行调用了fmt包中的Println函数,它的作用是打印出"hello world"。Println函数会自动在字符串的末尾添加一个换行符。
02-var
package main
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))
}
这段代码是用Go语言编写的一个简单程序,它展示了变量的声明、赋值和使用,以及常量的定义和使用。同时,它还使用了标准库中的fmt包来进行格式化输出,以及math包来进行数学运算。
下面是对代码的详细解释:
-
package main:声明这是一个名为main的包,每个Go程序都必须包含一个main包,它定义了程序的入口点。 -
import ("fmt"; "math"):导入了两个标准库包,fmt包用于格式化输入和输出,math包提供了数学函数和常量。 -
func main() {...}:定义了程序的入口函数main,程序从这里开始执行。 -
变量声明和赋值:
var a = "initial":声明一个字符串变量a并赋值为"initial"。var b, c int = 1, 2:同时声明两个整数变量b和c,并分别赋值为1和2。var d = true:声明一个布尔变量d并赋值为true。var e float64:声明一个浮点变量e,但没有立即赋值。f := float32(e):使用短变量声明符号:=声明一个新的变量f,并将e转换为float32类型后赋值给f。g := a + "foo":使用短变量声明符号:=声明一个新的变量g,并将a和"foo"拼接后赋值给g。
-
使用
fmt.Println打印变量的值:fmt.Println(a, b, c, d, e, f):打印变量a、b、c、d、e和f的值。fmt.Println(g):打印变量g的值。
-
常量的定义和使用:
const s string = "constant":定义一个字符串常量s并赋值为"constant"。const h = 500000000:定义一个整数常量h并赋值为500000000。const i = 3e20 / h:定义一个浮点常量i,其值为3e20除以h。
-
使用
fmt.Println打印常量的值和数学函数的结果:fmt.Println(s, h, i, math.Sin(h), math.Sin(i)):打印常量s、h、i的值,以及math.Sin(h)和math.Sin(i)的结果
03-for
package main
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 ++
}
}
go语言的for循环和c语言的差不多
04-if
package main
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")
}
}
if判断语句跟c语言相比少了括号,但判断及分支没变
05-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:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
}
跟c++相比少了括号
06-array
package main
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)
}
数组array大体跟Java、c++差不多
07-slice
package main
import "fmt"
func main() {
// 创建一个长度为3的字符串切片
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
// 输出切片的第三个元素(索引从0开始)
fmt.Println("get:", s[2]) // 输出: get: c
// 输出切片的长度
fmt.Println("len:", len(s)) // 输出: len: 3
// 使用 append 函数扩展切片,添加一个元素 "d"
s = append(s, "d")
// 再次使用 append 函数扩展切片,添加两个元素 "e" 和 "f"
s = append(s, "e", "f")
// 输出扩展后的切片
fmt.Println(s) // 输出: [a b c d e f]
// 创建一个新的切片 c,长度与 s 相同
c := make([]string, len(s))
// 将 s 中的内容复制到 c
copy(c, s)
// 输出复制后的切片 c
fmt.Println(c) // 输出: [a b c d e f]
// 输出切片 s 的第 2 到第 4 个元素(索引 2 到 4)
fmt.Println(s[2:5]) // 输出: [c d e]
// 输出切片 s 的前 5 个元素(索引 0 到 4)
fmt.Println(s[:5]) // 输出: [a b c d e]
// 输出切片 s 的第 2 个元素到最后一个元素(索引 2 到末尾)
fmt.Println(s[2:]) // 输出: [c d e f]
// 创建一个包含 "g", "o", "o", "d" 的切片
good := []string{"g", "o", "o", "d"}
// 输出切片 good
fmt.Println(good) // 输出: [g o o d]
}
以上代码展示了如何在 Go 语言中创建、修改、扩展和复制切片,以及如何使用切片的切片slice操作。
08-map
package main
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)
}
以上代码展示了Go语言如何操作映射map,包括创建、修改、查询、删除和初始化映射。
09-range
package main
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", "c":"C"}
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
}
}
以上代码展示了如何在 Go 语言中使用range 关键字遍历切片和映射。通过这些操作,可以灵活地处理集合中的数据。
10-func
package main
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
}
以上代码展示了Go语言如何定义和调用函数,包括简单的加法函数和一个检查映射中键是否存在并返回值的函数。
11-point
package main
import "fmt"
func add2(n int) {
n += 2
}
func add2ptr(n *int) {
*n += 2
}
func main() {
n := 5
add2(n)
fmt.Println(n) // 5
add2ptr(&n)
fmt.Println(n) // 7
}
Go语言的指针跟c++语言的指针一样
12-struct
package main
import "fmt"
type user struct {
name string
password string
}
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, "1024")) // false
fmt.Println(checkPassword2(&a, "1024")) // false
}
func checkPassword(u user, password string) bool {
return u.password == password
}
func checkPassword2(u *user, password string) bool {
return u.password == password
}
Go语言的结构体函数跟c++语言的结构体差不多
13-struct-method
package main
import "fmt"
type user struct {
name string
password string
}
func (u user) checkPassword(password string) bool {
return u.password == password
}
func (u *user) resetPassword(password string) {
u.password = password
}
func main() {
a := user{name: "wang", password: "1024"}
a.resetPassword("2048")
fmt.Println(a.checkPassword("2048")) // true
}
上述代码展示了如何在 Go 语言中定义结构体和方法,并使用这些方法来操作结构体的字段。通过值接收者和指针接收者的不同使用,可以灵活地实现不同的功能。值接收者适用于不需要修改结构体字段的方法,而指针接收者适用于需要修改结构体字段的方法。
14-error
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name) // wang
if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
fmt.Println(err) // not found
return
} else {
fmt.Println(u.name)
}
}
上述代码展示了如何在 Go 语言中定义结构体和方法,并在一个用户列表中查找特定的用户。通过使用指针返回找到的用户,可以避免不必要的拷贝。同时,通过返回错误信息,可以处理未找到用户的情况。这种设计使得代码更加健壮和易于维护。
15-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")) // 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)) // 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
}
这段代码展示了如何在 Go 语言中使用 strings 包中的各种字符串处理函数。通过这些函数,可以方便地进行字符串的查找、计数、分割、连接、替换、大小写转换等操作。同时,len 函数可以用来计算字符串的字节长度,这对于处理多字节字符(如中文字符)尤为重要。跟Java和C++的string封装类差不多。
16-fmt
package main
import "fmt"
type point struct {
x, y int
}
func main() {
s := "hello"
n := 123
p := point{1, 2}
fmt.Println(s, n) // hello 123
fmt.Println(p) // {1 2}
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=main.point{x:1, y:2}
f := 3.141592653
fmt.Println(f) // 3.141592653
fmt.Printf("%.2f\n", f) // 3.14
}
上述代码展示了如何在 Go 语言中使用 fmt 包中的各种格式化函数来打印不同类型的数据。通过这些函数,可以方便地进行字符串、整数、浮点数和结构体的格式化输出。特别是 fmt.Printf 函数提供了丰富的格式化选项,可以满足多种输出需求。
17-json
package main
import (
"encoding/json"
"fmt"
)
type userInfo struct {
Name string
Age int
Hobby []string
}
func main() {
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
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")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
err = json.Unmarshal(buf, &b)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}
上述代码展示了如何在 Go 语言中使用 encoding/json 包括序列化和反序列化结构体。通过 json.Marshal 和 json.Unmarshal 函数,可以方便地将结构体转换为 JSON 字符串,或将 JSON 字符串转换回结构体。json.MarshalIndent 函数提供了带缩进的 JSON 输出,使输出更易读。
18-time
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
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")
if err != nil {
panic(err)
}
fmt.Println(t3 == t) // true
fmt.Println(now.Unix()) // 1648738080
}
上述代码展示了如何在 Go 语言中使用 time 包来处理日期和时间。通过 time.Now、time.Date、time.Parse 等函数,可以方便地获取、创建、解析和格式化时间。time.Duration 类型用于表示时间间隔,可以进行时间差值的计算。Unix 方法用于获取时间的 Unix 时间戳,适用于需要时间戳的场景。
19-strconv
package main
import (
"fmt"
"strconv"
)
func main() {
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) // 1.234
n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n) // 111
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n) // 4096
n2, _ := strconv.Atoi("123")
fmt.Println(n2) // 123
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}
上述代码展示了如何在 Go 语言中使用 strconv 包中的函数将字符串转换为不同的数值类型。strconv.ParseFloat 用于将字符串转换为浮点数,strconv.ParseInt 用于将字符串转换为整数,并且可以指定基数,strconv.Atoi 用于将字符串转换为 int 类型。通过这些函数,可以方便地进行字符串和数值之间的转换,并处理可能的错误。
20-env
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("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
panic(err)
}
fmt.Println(string(buf)) // 127.0.0.1 localhost
}
上述代码展示了如何在 Go 语言中使用 os 和 os/exec 包来处理命令行参数、环境变量和外部命令的执行。通过 os.Args 可以获取命令行参数,os.Getenv 和 os.Setenv 可以获取和设置环境变量,exec.Command 和 CombinedOutput 可以执行外部命令并捕获其输出。这些功能在编写需要与操作系统交互的程序时非常有用。