欢迎光临
感谢一路有你

学习go语言第二天

如果你对该文章中的内容有疑问/不解,可以点击此处链接提问
要注明问题和此文章链接地址 点击此处跳转
 

数组切片

数组 - 定长序列,声明时需要指定长度:

var arr [5]int
arr[0] = 1
arr[1] = 2
fmt.Println(arr)
// [1 2 0 0 0]

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

切片 - 引用数组的可变长度片段:

slice := arr[1:3] // 创建切片 
slice = append(slice, 4) // 追加元素
fmt.Println(slice) //[2 0 4]
// 切片使用len()获取长度,cap()获取容量。
fmt.Println(len(slice), cap(slice)) // 3 4

for循环

// for循环遍历数组或切片:
for i := 0; i < len(slice); i++ {
	fmt.Println(slice[i])
}
// 2
// 0
// 4


// for range遍历数组或切片:
for i, v := range arr {
	println(i, v)
}
// 0 1
// 1 2
// 2 0
// 3 4
// 4 0

其中range关键字可以遍历数组/切片,返回索引和值。
切片比数组更常用,可以灵活添加元素。我们通常用for range循环来遍历切片

流程控制

条件判断 - if语句:

x := 10
if x > 10 {
	fmt.Println("x is greater than 10")
} else {  
	fmt.Println("x is less than 10")
}

多条件判断 - switch语句:

operatingSystem := "linux"
switch operatingSystem {
case "darwin":
  fmt.Println("Mac OS")
case "linux":
  fmt.Println("Linux")  
default:
  fmt.Println("Other System")
}

循环语句 - for循环:

	for i := 0; i < 5; i++ {
		fmt.Println(i)
	}

循环控制语句:
continue:跳过当前循环,开始下一次循环
break:完全终止循环
goto:直接跳转到标签
defer语句 - 延迟调用:

defer fmt.Println("defer statement")

函数的使用

定义函数

func functionName(input1 type1, input2 type2) (output1 type1, output2 type2) {
  // 函数体代码
  return value1, value2 
}

函数参数:
可以有多个输入参数,按类型声明
可以有多个返回值,或无返回值
调用函数

result1, result2 := functionName(param1, param2)

匿名函数

func(paramType) returnType {
  // ...
}

闭包函数

func outer() func() {
  x := 10
  return func() {
    fmt.Println(x) 
  }
}

Go语言函数支持多参数、多返回值、匿名函数和闭包等特性,用法灵活。可以实现一类通用逻辑,提高代码复用性。

简单的算法程序

package main
import "fmt"


func AvgNum(nums ...int) int{
	var total int
	for _, num := range nums{
		total += num
	}
	return total / len(nums)
}
func AvgNum2(nums []int) int{
	var total int
	for _, num := range nums{
		total += num
	}
	return total / len(nums)
}

func main(){
	fmt.Println(AvgNum(1,2,3,4,5,6,7,8,9,10))
	fmt.Println(AvgNum2([]int{1,2,3,4,5,6,7,8,9,10}))

}

包管理

Go语言的包管理主要通过如下方式:

导入包
在代码顶部导入需要的包,如:

import "fmt"
import "os"

init()函数
包中的init()函数会在包加载时自动执行。

包作用域
函数名和变量名都是包级作用域,可以通过包名来访问。

包名约定
按照目录命名,同一个目录下的Go文件属于一个包。

包依赖管理
Go Modules来管理依赖版本,在Go 1.13+后是默认方式。

主要命令:

go mod init 初始化
go get 添加依赖
go mod tidy 整理依赖
go mod graph 查看依赖图
包的可见性
通过大写字母开头的导出名来控制对外可见性。

掌握了包的使用方法,可以组织代码结构,有效复用代码。

包的简单应用

好的,这里以编写一个数字计算的简单包为例:

  1. 在自己的工作区创建 calc 包目录:$GOPATH/src/calc

  2. 在该目录下创建calc.go文件:

package calc

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

func Sub(a, b int) int {
  return a - b  
}
  1. 在同一目录创建calc_test.go测试文件:
package calc

import "testing"

func TestAdd(t *testing.T) {
  if Add(1, 2) != 3 {
    t.Error("Add failed") 
  } 
}
  1. 其他程序可以通过导入这个包来使用:
import "calc"

calc.Add(1, 2) 
  1. 也可以为包起别名:
import c "calc" 

c.Add(1, 2)

以上演示了如何编写一个简单的包,包含函数、测试、导入使用等,可以作为练习包管理的示例。

structs和methods

package main
import "fmt"

// 定义一个User结构体 
type User struct {
	Id   int
	Name string
	Age  int
  }
  
  // 为User结构体定义方法
  func (u User) ToString() string {
	return fmt.Sprintf("User: %d %s %d", u.Id, u.Name, u.Age)
  }
  
  func main() {
	// 创建User对象
	user := User{Id: 1, Name: "张三", Age: 23}
	
	// 调用method
	fmt.Println(user.ToString())
  }

输出:
User: 1 张三 23
这里定义了一个User结构体,包含了Id、Name和Age字段。
然后为User结构体定义了ToString方法,该方法可以输出用户信息。
在main函数中,我们创建了User对象user,然后就可以直接调用user.ToString()方法。
这样便实现了基于struct和method的面向对象编程。

指针

package main

import "fmt"

func main() {
  var a int = 10
  
  // 指针ptr指向a
  var ptr *int = &a
  
  // 通过指针读取a的值
  fmt.Println(*ptr)
  
  // 通过指针修改a的值
  *ptr = 20
  
  fmt.Println(a)
}
示例解读:

声明变量a,初始值为10
声明指针ptr,存储变量a的地址 &a
可以通过 deferencing *ptr 读取指针指向的变量值
通过指针ptr修改变量a的值为20
打印a输出20,说明指针ptr通过引用修改了a
指针是Go语言实现引用传递的基础。正确使用指针可以在函数间传递引用而不仅是拷贝值。

map

这里是一个Go语言中map使用的简单示例:

package main

import "fmt"

func main() {
  // 创建map
  ages := make(map[string]int)
  
  // 添加键值对
  ages["Alice"] = 25
  ages["Bob"] = 30
  
  // 读取数据
  fmt.Println(ages["Alice"])
  
  // 遍历map
  for name, age := range ages {
    fmt.Println(name, age)
  }
  
  // 判断某键是否存在
  _, ok := ages["Charlie"]
  if !ok {
    fmt.Println("Charlie not found") 
  }
}


示例解读:

1. 使用make创建map,键是字符串,值是int

2. 通过 key=value 语法插入键值对

3. 通过 key 读取值,如果不存在则返回值类型的零值

4. 可以遍历map获取到所有的键值对

5. 用value, ok := map[key]判断key是否存在

map是Go语言内建的哈希表实现,可以通过键快速查找值,非常实用。

为什么要使用匿名变量

在Go语言中,使用 _ 下划线声明的变量为匿名变量,通常用于忽略不需要的返回值。
在判断map中键是否存在的示例代码中:

_, ok := ages["Charlie"]

map在访问一个键时会返回两个值,第一个值是该键对应的值,第二个值是一个布尔值,表示该键是否存在。
这里我们不需要访问的值,只需要知道该键是否存在。所以使用 _ 忽略了第一个返回值,只获取了第二个返回值ok,来判断键是否存在。
如果写成:

value, ok := ages["Charlie"] 

那么value会获取到值类型的零值。我们不需要value变量,所以使用匿名变量_忽略第一个返回值,这样代码更简洁。

所以Go语言中的匿名变量_ 主要用于丢弃不需要的返回值,从而简化代码。

赞(1) 打赏
未经允许不得转载:王明昌博客 » 学习go语言第二天
分享到: 更多 (0)

相关推荐

  • 暂无文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

×
订阅图标按钮