1 Go基础语法
由于Go的基础语法从设计思路上看上去是对C的扩充,因此只记录Go和C不同的地方。本文假设读者拥有C和Cpp的基础,在此基础上简要介绍Go的基础语法。
1.1 变量定义
var a = "abc" // 声明变量,自动推导类型
var b int = 1 // 声明变量和类型
f := float32(0.5) // 自动推导
1.2 流程控制
1.2.1 if else 流程控制
// if后不需要括号
if 1<2 {
fmt.Println("1<2")
} else {
fmt.Println("1>2")
}
// if后可以先有表达式
if num := 7; num < 9 {
fmt.Println("num<9")
} else if num < 20 {
fmt.Println("num>9, num<20")
} else {
fmt.Println("num>=20")
}
1.2.2 for 循环
go只有for循环一种形式
Go语言中的`for`循环可以有多种形式,可以省略或不省略每个部分。下面我会分别介绍这些形式:
-
完整形式:
for 初始化语句; 循环条件; 后续语句 { // 循环体 }在完整形式中,首先执行初始化语句,然后在每次循环开始前,检查循环条件是否为真。如果条件为真,则执行循环体,并在循环体执行完后执行后续语句。这个过程会一直重复,直到循环条件为假。
- 省略初始化语句:
for ; 循环条件; 后续语句 { // 循环体 }在这种形式中,省略了初始化语句,因此在循环开始前不会执行任何代码。其他部分与完整形式相同。
-
省略后续语句:
for 初始化语句; 循环条件; { // 循环体 }在这种形式中,省略了后续语句,因此在每次循环结束后不会执行任何代码。其他部分与完整形式相同。
-
完全省略:
for 循环条件 { // 循环体 }在完全省略形式中,只提供循环条件。这将变成类似于其他语言中的
while循环,条件为真时执行循环体,直到条件为假才停止循环。值得注意的是,Go语言中没有传统的
while循环结构,但通过省略初始化语句和后续语句,可以实现类似的效果。另外,在循环中,循环条件表达式的结果必须是布尔值。若条件为真,则执行循环体,否则退出循环。以下是一个简单的示例,展示了上述不同形式的
for循环:package main import "fmt" func main() { // 完整形式 for i := 0; i < 5; i++ { fmt.Println("完整形式:", i) } // 省略初始化语句 j := 0 for ; j < 5; j++ { fmt.Println("省略初始化语句:", j) } // 省略后续语句 k := 0 for k < 5 { fmt.Println("省略后续语句:", k) k++ } // 完全省略 l := 0 for l < 5 { fmt.Println("完全省略:", l) l++ } }
1.2.3 switch流程控制
- go的switcg不需要使用break:
package main
import "fmt"
func main() {
i := 5
switch i {
case 1:
fmt.Println("i is equal to 1")
case 2, 3, 4:
fmt.Println("i is between 2 and 4")
case 5:
fmt.Println("i is equal to 5")
default:
fmt.Println("i is not between 1 and 5")
}
}
- go的switch可以不接表达式,而是将其放在case中:
```go
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println(" after noon")
default:
fmt.Println(" before noon")
}
```
1.2.4 range语法
range 关键字用于迭代数组、切片、映射、通道和字符串等数据结构。range 关键字返回两个值:第一个值是当前迭代的元素的索引或键,第二个值是当前迭代的元素的值。
```go
// 迭代一个整型数组
a := []int{1, 2, 3, 4, 5}
for i, v := range a {
fmt.Println(i, v)
}
// 迭代一个字符串
s := "hello, world"
for i, c := range s {
fmt.Println(i, c)
}
// 迭代一个映射
m := map[string]int{"apple": 1, "banana": 2, "cherry": 3}
for k, v := range m {
fmt.Println(k, v)
}
```
需要注意的是,如果不需要使用 index 或 value 变量,可以使用下划线 _ 代替,例如:
```
// 只迭代字符串中的字符值,忽略字符位置
s := "hello, world"
for _, c := range s {
fmt.Println(c)
}
```
1.3 数据结构
1.3.1 数组和切片
- 定义数组:
var a [5] int
-
定义切片 在 Go 语言中,
make()函数用于创建 slice、map 和 channel 等数据结构。下面用make()函数创建切片:make([]T, length, capacity)T:切片的元素类型。length:切片的长度。capacity:切片的容量(可选)。如果未指定容量,则容量等于长度。
示例:
// 创建一个长度为5,容量为10的整型切片 s := make([]int, 5, 10)切片的其他语法与Python类似
其他切片语法:
```go
// 创建两个字符串切片
s1 := []string{"foo", "bar"}
s2 := []string{"baz", "qux"}
// 拼接两个切片
s3 := append(s1, s2...)
// 获取切片的长度
length := len(s3)
// 获取切片的容量
capacity := cap(s3)
// 从一个数组或切片中创建切片
s = s[start:end] // 从切片中获取[start, end)的元素组成的切片
// 向切片中添加元素
s = append(s, 4, 5)
```
1.3.2 map
map 是一种无序键值对的集合。可以使用任何可以使用 == 运算符比较的类型作为键,例如整数、浮点数、字符串、指针、结构体、数组、切片和接口类型等。map 通过哈希表实现,因此查找、插入和删除操作的时间复杂度为常数级别。 基本语法: ```go // 创建一个空 map var m map[keyType]valueType
// 创建一个初始容量为n的 map
m := make(map[keyType]valueType, n)
// 使用[]运算符访问映射中的元素
fmt.Println(m["apple"]) // 输出:1
// 删除映射中的元素
delete(m, "banana")
// 遍历映射中的元素
for k, v := range m {
fmt.Println(k, v)
}
```
1.3.3 字符串
-
字符串操作 在 Go 语言中,字符串是一个不可变的字节序列,可以使用一些内置的函数和标准库函数来操作字符串。以下是一些常见的字符串操作函数:
len函数:返回字符串的长度,即包含的字节数。
示例:
s := "hello world" fmt.Println(len(s)) // 输出 11+运算符:可以将两个字符串拼接起来,生成一个新的字符串。
示例:
s1 := "hello" s2 := "world" s3 := s1 + " " + s2 fmt.Println(s3) // 输出 "hello world"strings.Contains函数:判断一个字符串是否包含另一个字符串。
示例:
s := "hello world" if strings.Contains(s, "world") { fmt.Println("包含") } else { fmt.Println("不包含") }strings.Split函数:将一个字符串按照指定的分隔符分割成多个子串,并返回一个字符串切片。
示例:
s := "a,b,c,d" a := strings.Split(s, ",") fmt.Println(a) // 输出 [a b c d]strings.Join函数:将多个子串按照指定的分隔符拼接成一个字符串。
示例:
a := []string{"hello", "world"} s := strings.Join(a, " ") fmt.Println(s) // 输出 "hello world"strings.ToUpper和strings.ToLower函数:将一个字符串转换为全大写或全小写。
示例:
s := "Hello, World!" s1 := strings.ToUpper(s) s2 := strings.ToLower(s) fmt.Println(s1) // 输出 "HELLO, WORLD!" fmt.Println(s2) // 输出 "hello, world!"strings.TrimSpace函数:去掉字符串开头和结尾的空白字符。
示例:
s := " hello world " s1 := strings.TrimSpace(s) fmt.Println(s1) // 输出 "hello world"strings.Replace函数:将一个字符串中的指定子串替换为另一个子串。
示例:
s := "hello world" s1 := strings.Replace(s, "world", "go", -1) fmt.Println(s1) // 输出 "hello go"strings.Count函数:统计一个字符串中包含指定子串的个数。
s := "hello world" count := strings.Count(s, "l") fmt.Println(count) // 输出 3- strings.HasPrefix/HasSuffix 函数:判断一个字符串是否以指定的前缀开头。
Copy s := "hello world" if strings.HasPrefix(s, "hello") { fmt.Println("以 hello 开头") } else { fmt.Println("不以 hello 开头") } // strings.HasSuffix 函数语法类似strings.Index函数:查找子串在字符串中第一次出现的位置,如果找不到则返回 -1。
s := "hello world" index := strings.Index(s, "world") fmt.Println(index) // 输出 6 -
字符串格式化 在 Go 语言中,字符串格式化是一种常见的操作,用于将数据格式化为字符串,可以通过一些占位符来指定数据的类型、宽度、精度等信息。以下是 Go 语言中字符串格式化的语法:
-
%v:通用占位符,可以用来表示任意类型的值,会自动根据值的类型进行格式化。示例:
var a = 10 var b = "hello" var c = true fmt.Printf("%v, %v, %v\n", a, b, c) // 输出 "10, hello, true" -
%d:表示整数类型(十进制)。示例:
var a = 10 fmt.Printf("%d\n", a) // 输出 "10" -
%f:表示浮点数类型(小数点后默认保留 6 位)。示例:
var pi = 3.1415926 fmt.Printf("%f\n", pi) // 输出 "3.141593" fmt.Printf("%.2f\n", pi) // 输出 "3.14" fmt.Printf("%.4f\n", pi) // 输出 "3.1416" fmt.Printf("%.6f\n", pi) // 输出 "3.141593" -
%s:表示字符串类型。示例:
var a = "hello" fmt.Printf("%s\n", a) // 输出 "hello" -
%t:表示布尔类型,输出 true 或 false。示例:
var a = true fmt.Printf("%t\n", a) // 输出 "true" -
%x和%X:表示十六进制整数类型,输出小写或大写的十六进制数。示例:
var a = 255 fmt.Printf("%x\n", a) // 输出 "ff" fmt.Printf("%X\n", a) // 输出 "FF" -
%p:表示指针类型,输出指针的十六进制地址。示例:
var a = &[]int{1, 2, 3} fmt.Printf("%p\n", a) // 输出 "0xc00000a080"(地址会根据实际情况而变化)
上述语法中的占位符可以和其他字符一起使用,例如
%d、%d%%表示输出整数类型并且带百分号。此外,还可以使用一些修饰符来指定输出的宽度、精度、对齐方式等信息,例如%5d表示输出宽度为 5 的整数类型,不足的地方用空格补齐。更多格式化语法和修饰符的使用方法,请参考 Go 语言官方文档。 -
1.4 函数
1.4.1 基本语法
Go的函数与C语言的区别主要在于可以返回多个值。Go 语言中的函数定义语法如下:
func function_name(parameter_list) return_type {
// 函数体
return result
}
其中,function_name 表示函数名,parameter_list 表示函数的参数列表,return_type 表示函数的返回值类型,result 表示函数的返回值。
示例:
// 定义一个函数,计算两个整数之和
func add(a, b int) int {
return a + b
}
// 调用函数,并打印结果
sum := add(1, 2)
fmt.Println(sum)
1.4.2 多个返回值
Go 语言中的函数可以有多个返回值,例如:
// 定义一个函数,返回两个整数的商和余数
func divmod(a, b int) (int, int) {
return a / b, a % b
}
// 调用函数,并打印结果
quotient, remainder := divmod(10, 3)
fmt.Println(quotient, remainder)
可以使用 _ 代替不需要的返回值,例如:
// 定义一个函数,返回两个整数的和和差
func addsub(a, b int) (int, int) {
return a + b, a - b
}
// 调用函数,并忽略第二个返回值
sum, _ := addsub(3, 2)
fmt.Println(sum)
1.4.3 函数闭包
函数也可以作为参数传递给其他函数或闭包。这种函数类型的参数或返回值可以用作函数签名,例如:
// 定义一个函数类型,表示两个整数的运算函数
type operation func(int, int) int
// 定义一个函数,接受一个运算函数和两个整数,返回运算结果
func apply(op operation, a, b int) int {
return op(a, b)
}
// 调用函数,并传递一个函数作为参数
sum := apply(func(a, b int) int { return a + b }, 1, 2)
fmt.Println(sum)
1.5 指针
Go的指针语法如下:
a := 3
var p *int
p = &a
// 空指针为nil
p = nil
与C语言相比,Go的指针功能受限,不能像 C 语言中那样对指针进行加减运算。这是为了避免出现指针溢出或越界的情况,从而提高程序的安全性。
1.6 结构体
1.6.1 定义结构体
在 Go 语言中,结构体是一种自定义的复合类型,可以由若干个成员(字段)组成。每个字段可以是任意类型,包括其他结构体类型。结构体可以用于表示复杂的数据结构,例如二维坐标、人员信息等等。Go 语言中的结构体定义语法如下:
```go
type struct_name struct {
field1 type1
field2 type2
...
}
```
其中,`struct_name` 表示结构体的名称,`field1`、`field2` 等表示结构体的字段名,`type1`、`type2` 等表示字段的类型。
示例:
```go
// 定义一个二维坐标结构体
type point struct {
x int
y int
}
// 创建一个坐标点
p := point{x: 1, y: 2}
// 访问结构体的字段
fmt.Println(p.x, p.y)
```
1.6.2 结构体方法
可以为结构体定义方法(Method),方法是一种与结构体关联的函数,类比C++的成员函数。Go 语言中的方法定义语法如下:
```go
func (receiver type) method_name(parameter_list) return_type {
// 方法体
}
```
其中,`receiver` 表示方法的接收者,可以是值接收者或指针接收者,`method_name` 表示方法的名称,`parameter_list` 和 `return_type` 分别表示方法的参数列表和返回值类型。
示例:
```go
// 定义一个二维坐标结构体
type point struct {
x int
y int
}
// 为结构体定义一个方法,计算两个坐标之间的距离
func (p point) distance(q point) float64 {
dx := float64(q.x - p.x)
dy := float64(q.y - p.y)
return math.Sqrt(dx*dx + dy*dy)
}
// 创建两个坐标点
p1 := point{x: 1, y: 2}
p2 := point{x: 4, y: 6}
// 调用结构体的方法
d := p1.distance(p2)
fmt.Println(d)
```
1.6.3 接收者类型
需要注意的是,值接收者是将结构体的副本传递给方法,而指针接收者是将结构体的地址传递给方法。使用指针接收者可以避免在方法中复制结构体,从而提高程序的效率。另外,如果方法需要修改结构体的字段,必须使用指针接收者。例如:
```go
// 为结构体定义一个方法,将坐标点沿 x 轴平移
func (p *point) translate(dx int) {
p.x += dx
}
// 创建一个坐标点
p := point{x: 1, y: 2}
// 调用结构体的方法,并修改结构体的字段
p.translate(2)
fmt.Println(p.x, p.y)
```
1.8 错误处理
1.8.1 error接口
Go 语言通过内置的 `error` 接口类型来表示错误,并提供了一些标准库函数和语言特性,用于处理和返回错误。
在 Go 语言中,`error` 接口类型定义如下:
```go
type error interface {
Error() string
}
```
其中,`Error()` 方法返回一个字符串,表示错误的描述信息。
1.8.2 errors.New
在函数或方法中,如果遇到错误,可以通过返回一个非空的 `error` 类型值来表示错误。例如:
```go
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
result, err := divide(10, 2)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
```
在上面的例子中,`divide` 函数返回两个值:商和错误。如果除数为零,函数将返回一个非空的 `error` 类型值,其中包含错误信息。在调用 `divide` 函数时,可以通过判断返回的 `error` 类型值是否为 `nil` 来确定函数是否执行成功。
1.8.3 格式化错误信息
除了使用 `errors.New` 函数创建错误信息外,还可以使用 `fmt.Errorf` 函数创建一个带格式的错误信息。例如:
```go
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero, a=%d, b=%d", a, b)
}
return a / b, nil
}
result, err := divide(10, 0)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
```
1.8.4 defer和recover
除了返回错误外,Go 语言还提供了一种类似于 `try-catch` 的机制,即 `defer-painc-recover`。`defer` 语句可以延迟执行函数中的代码,`panic` 函数可以在函数中引发异常,`recover` 函数可以捕获异常并进行处理。例如:
```go
func divide(a, b int) int {
defer func() {
if r := recover(); r != nil {
fmt.Println("recover from:", r)
}
}()
if b == 0 {
panic("division by zero")
}
return a / b
}
result := divide(10, 0)
fmt.Println(result)
```
在上面的例子中,`divide` 函数使用 `panic` 函数在除数为零时引发异常,然后使用 `recover` 函数捕获异常并打印出错误信息。需要注意的是,`defer` 语句必须在 `panic` 函数之前执行,否则无法捕获异常。
1.9 常见数据处理
1.9.1 json处理
在 Go 语言中,处理 JSON 数据非常方便,标准库中提供了 encoding/json 包,该包提供了 Marshal、Unmarshal 和 MarshalIndent 等函数,使得 JSON 格式的数据与 Go 语言的结构体之间可以方便地相互转换。
1.9.1.1 Marshal 函数
Marshal 函数用于将 Go 语言的结构体转换为 JSON 格式的字符串。函数签名如下:
func Marshal(v interface{}) ([]byte, error)
其中,参数 v 表示要转换的 Go 语言结构体,函数返回值是一个字节数组和一个 error 类型的错误信息。
示例:
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
person := Person{Name: "Tom", Age: 18}
data, err := json.Marshal(person)
if err != nil {
fmt.Println("JSON 格式化失败:", err)
} else {
fmt.Println(string(data))
}
// 输出:{"name":"Tom","age":18}
1.9.1.2 Unmarshal 函数
Unmarshal 函数用于将 JSON 格式的字符串转换为 Go 语言的结构体。函数签名如下:
func Unmarshal(data []byte, v interface{}) error
其中,参数 data 表示要转换的 JSON 格式的字节数组,参数 v 表示要转换为的 Go 语言结构体,函数返回值是一个 error 类型的错误信息。
示例:
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
str := `{"name":"Tom","age":18}`
var person Person
err := json.Unmarshal([]byte(str), &person)
if err != nil {
fmt.Println("JSON 解析失败:", err)
} else {
fmt.Println(person.Name, person.Age)
}
// 输出:Tom 18
1.9.1.3 MarshalIndent 函数
MarshalIndent 函数和 Marshal 函数的作用相同,不同之处在于 MarshalIndent 函数会将生成的 JSON 格式的字符串进行格式化,使其更易于阅读。函数签名如下:
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
其中,参数 v 表示要转换的 Go 语言结构体,prefix 表示每一行前缀使用的字符串,indent 表示缩进使用的字符串,函数返回值是一个字节数组和一个 error 类型的错误信息。
示例:
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
person := Person{Name: "Tom", Age: 18}
data, err := json.MarshalIndent(person, "", " ")
if err != nil {
fmt.Println("JSON 格式化失败:", err)
} else {
fmt.Println(string(data))
}
// 输出:
// {
// "name": "Tom",
// "age": 18
// }
上述示例中的 Person 结构体中的 json 标签用于指定 JSON 格式中对应字段的名称。在实际使用中,可以根据需要选择使用 json 标签。
1.9.2 时间库
在 Go 语言中,标准库 time 提供了丰富的时间处理函数和类型,可以方便地对时间进行格式化、解析、计算等操作。以下是一些常用的时间处理函数:
1.9.2.1 Now 函数
Now 函数返回当前本地时间。函数签名如下:
func Now() time.Time
示例:
now := time.Now()
fmt.Println(now) // 输出:2023-08-02 14:15:16.123456789 +0800 CST m=+0.000123456
1.9.2.2 Parse 函数
Parse 函数将字符串解析为时间。函数签名如下:
func Parse(layout, value string) (Time, error)
其中,参数 layout 是时间格式字符串,value 是要解析的时间字符串,函数返回值是一个 Time 类型的时间和一个 error 类型的错误信息。
示例:
str := "2023-08-02 14:15:16"
t, err := time.Parse("2006-01-02 15:04:05", str)
if err != nil {
fmt.Println("时间解析失败:", err)
} else {
fmt.Println(t) // 输出:2023-08-02 14:15:16 +0000 UTC
}
1.9.2.3 Format 函数
Format 函数将时间格式化为字符串。函数签名如下:
func (t Time) Format(layout string) string
其中,参数 layout 是时间格式字符串,函数返回值是一个字符串类型的时间。
示例:
now := time.Now()
str := now.Format("2006-01-02 15:04:05")
fmt.Println(str) // 输出:2023-08-02 14:15:16
1.9.2.4 Add 函数
Add 函数用于给时间加上一个时间段。函数签名如下:
func (t Time) Add(d Duration) Time
其中,参数 d 是一个时间段,可以使用 time.Second、time.Minute、time.Hour 等常量表示。
示例:
now := time.Now()
later := now.Add(time.Hour * 24)
fmt.Println(later) // 输出:2023-08-03 14:15:16.123456789 +0800 CST
1.9.2.5 Sleep 函数
Sleep 函数用于让当前程序休眠一段时间。函数签名如下:
func Sleep(d Duration)
其中,参数 d 是一个时间段,可以使用 time.Second、time.Millisecond 等常量表示。
示例:
fmt.Println("start")
time.Sleep(time.Second)
fmt.Println("end")
上述示例中的程序会在输出 "start" 后休眠 1 秒钟,然后输出 "end"。
除了上述函数外,标准库 time 还提供了许多其他的时间处理函数,例如 Tick、Since、Until 等函数,可以根据需要选择使用。
1.9.3 字符串和数值类型转换
在 Go 语言中,字符串和数值类型之间的相互转换非常方便,可以使用标准库中的 strconv 包提供的函数进行转换。以下是一些常用的字符串和数值类型之间的转换函数:
1.9.3.1 字符串转整数
Atoi 函数可以将字符串转换为整数。函数签名如下:
func Atoi(s string) (int, error)
其中,参数 s 是要转换的字符串,函数返回值是一个 int 类型的整数和一个 error 类型的错误信息。
示例:
str := "123"
i, err := strconv.Atoi(str)
if(err != nil) {
fmt.Println("字符串转整数失败:", err)
} else {
fmt.Println(i) // 输出:123
}
1.9.3.2 字符串转浮点数
ParseFloat 函数可以将字符串转换为浮点数。函数签名如下:
func ParseFloat(s string, bitSize int) (float64, error)
其中,参数 s 是要转换的字符串,bitSize 表示浮点数的精度,可以使用 32 表示 float32 类型,64 表示 float64 类型。函数返回值是一个 float64 类型的浮点数和一个 error 类型的错误信息。
示例:
str := "3.14"
f, err := strconv.ParseFloat(str, 64)
if err != nil {
fmt.Println("字符串转浮点数失败:", err)
} else {
fmt.Println(f) // 输出:3.14
}
1.9.3.3 整数转字符串
Itoa 函数可以将整数转换为字符串。函数签名如下:
func Itoa(i int) string
其中,参数 i 是要转换的整数,函数返回值是一个字符串类型的整数。
示例:
i := 123
str := strconv.Itoa(i)
fmt.Println(str) // 输出:"123"
1.9.3.4 浮点数转字符串
FormatFloat 函数可以将浮点数转换为字符串。函数签名如下:
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
其中,参数 f 是要转换的浮点数,fmt 表示格式化方式,可以使用 'f' 表示普通浮点数,'e' 表示科学计数法,'g' 表示根据实际情况选择普通浮点数或科学计数法;prec 表示精度,bitSize 表示浮点数的精度。
示例:
f := 3.14
str := strconv.FormatFloat(f, 'f', 2, 64)
fmt.Println(str) // 输出:"3.14"
上述示例中的 bitSize 参数表示浮点数的精度,可以使用 32 表示 float32 类型,64 表示 float64 类型。在使用时需要根据实际情况选择合适的精度。
1.10 系统库函数
在 Go 语言中,可以通过标准库中的 os 包来获取环境变量和命令行参数,以及调用可执行程序。下面分别介绍这些操作的方法:
1.10.1 获取环境变量
可以使用 os 包中的 Getenv 函数来获取环境变量的值。函数签名如下:
func Getenv(key string) string
其中,参数 key 是环境变量的名称,函数返回值是一个字符串类型的环境变量值。
示例:
path := os.Getenv("PATH")
fmt.Println("PATH:", path)
1.10.2 获取命令行参数
可以使用 os 包中的 Args 变量来获取命令行参数。Args 是一个字符串切片,第一个元素是程序的路径,后面的元素是命令行参数。示例:
args := os.Args
fmt.Println("命令行参数:", args)
1.10.3 调用可执行程序
可以使用 os 包中的 StartProcess 函数来调用可执行程序。函数签名如下:
func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error)
其中,参数 name 是可执行程序的名称,argv 是传递给可执行程序的命令行参数,attr 是一个 ProcessAttributes 类型的结构体,包含一些进程属性的设置,例如环境变量、工作目录、文件描述符等。函数返回值是一个 Process 类型的结构体和一个 error 类型的错误信息。
示例:
cmd := exec.Command("ls", "-l")
out, err := cmd.Output()
if err != nil {
fmt.Println("命令执行失败:", err)
} else {
fmt.Println(string(out))
}
上述示例中的代码调用了 ls 命令,并输出了其执行结果。在调用可执行程序时,也可以使用其他函数,例如 CombinedOutput、Run 等函数,根据需要选择使用。