0
点赞
收藏
分享

微信扫一扫

Go基本数据结构

棒锤_45f2 2024-10-09 阅读 17

目录

一、Go中的函数

函数声明

 多个返回值

可变参数

匿名函数

值传递和地址传递

函数执行顺序(init函数)

二、Go中的包

基本语法

主要包(main package)

导入其他包

包的作用域

包的使用

包名别名

小结


一、Go中的函数

        Go中的函数与其他函数中功能大差不差,只是格式不同,当然也更加简便,从中可以看到其他语言的影子,但是开发效率会高上不少。

一个简单的Go函数定义如下:

package main

import "fmt"

// 定义一个名为 add 的函数,接受两个 int 参数,返回一个 int 结果
func add(a int, b int) int {
    return a + b
}

func main() {
    // 调用 add 函数
    result := add(2, 3)
    fmt.Println("结果是:", result)
}

 多个返回值

我们的返回值列表也可以设置多返回值,这个C++中可能就要设置自定义数据类型或者模板来实现,而Go提供了很便捷的方法,直接定义返回值列表返回即可

func divide(a int, b int) (int, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为零")
    }
    return a / b, nil
}

func main() {
    result, err := divide(10, 2)
    if err != nil {
        fmt.Println("错误:", err)
    } else {
        fmt.Println("结果是:", result)
    }
}

可变参数

如果你想要传递可变数量的参数给一个函数,可以使用 ... 操作符

func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

func main() {
    result := sum(1, 2, 3, 4, 5)
    fmt.Println("总和是:", result)
}

匿名函数

你也可以定义匿名函数,并将其赋值给一个变量或立即调用:

func main() {
    sum := func(nums ...int) int {
        total := 0
        for _, num := range nums {
            total += num
        }
        return total
    }

    result := sum(1, 2, 3, 4, 5)
    fmt.Println("总和是:", result)
}

我们来看这一种情况,将函数赋值给一个变量,这个变量就是一个函数,和我们之前学习的函数指针非常像,回调函数的场景应用非常多


func test(args ...int) {
	//函数内部处理可变参数,将可变参数当作切片来处理
	for i := 0; i < len(args); i++ {
		fmt.Println(args[i])
	}
}
func test2(num1 int, num2 int, funct func(args ...int)) {
	funct(num1, num2)
}
func main() {
	//var a = 10
	//var b = 20
	//exchange(&a, &b)
	//fmt.Println(a)
	//fmt.Println(b)
	test(1, 2, 3, 4, 5, 6, 7, 8, 6, 55)
	c := test
	fmt.Printf("c:%T,test:%T\n", c, test)
	c(1, 2, 3, 5, 6, 7, 8)
	test2(1, 2, test) //test和C是完全一样的
	test2(1, 2, c)
}

 可以看到c和test的类型没有任何区别

值传递和地址传递

在C语言中我们直到形参的改变不会引起实参的改变,所以我们需要传递实参的地址 

package main

import "fmt"

func exchange(num1 *int, num2 *int) {
	var tmp int = *num1
	*num1 = *num2
	*num2 = tmp
}

func test(args ...int) {
	//函数内部处理可变参数,将可变参数当作切片来处理
	for i := 0; i < len(args); i++ {
		fmt.Println(args[i])
	}
}
func test2(num1 int, num2 int, funct func(args ...int)) {
	funct(num1, num2)
}
func main() {
	var a = 10
	var b = 20
	exchange(&a, &b)
	fmt.Println(a)
	fmt.Println(b)
	test(1, 2, 3, 4, 5, 6, 7, 8, 6, 55)
	//c := test
	fmt.Printf("c:%T,test:%T", c, test)
	c(1, 2, 3, 5, 6, 7, 8)
	//test2(1, 2, test)
	//test2(1, 2, c)
}

函数执行顺序(init函数)

 下面是一个综合示例,展示了全局变量初始化、包级别的 init 函数和 main 函数的执行顺序

// pkg1/init.go
package pkg1

var x = initX()

func initX() int {
    println("初始化 pkg1.x")
    return 10
}

func init() {
    println("pkg1 的 init 函数")
}

// pkg2/init.go
package pkg2

var y = initY()

func initY() int {
    println("初始化 pkg2.y")
    return 20
}

func init() {
    println("pkg2 的 init 函数")
}

// main/main.go
package main

import (
    "pkg1"
    "pkg2"
)

func main() {
    println("main 函数开始")
    println("pkg1.x 的值:", pkg1.x)
    println("pkg2.y 的值:", pkg2.y)
}

输出是

二、Go中的包

        在 Go 语言中,包(package)是一个重要的概念,用于组织和复用代码。通过使用包,你可以将相关的函数、类型、变量等组织在一起,从而提高代码的可维护性和可读性。

基本语法

每个 Go 文件必须属于一个包。包的声明位于文件的顶部:

package mypackage

其中 mypackage 是包的名称。通常,包名会反映其功能或用途(一般建议包名和文件夹名称相同)

主要包(main package)

一个特殊的包是 main 包,它是程序的入口点。当编译和运行一个 Go 程序时,默认情况下会编译 main 包。main 包中的 main 函数是程序执行的起点:

package main

import "fmt"

func main() {
    fmt.Println("Hello, world!")
}

导入其他包

你可以通过 import 语句来导入其他包。导入语句通常位于包声明之后,但在任何其他代码之前

如果导入多个包,可以使用这种写法更为便捷

import (
    "fmt"      // 标准库包
    "mypackage" // 自定义包
)

包的作用域

在 Go 中,包内的标识符(如变量、函数、类型等)默认具有包级作用域,这意味着它们只能在同一包内访问。为了使一个标识符在其他包中也能访问,需要将其首字母大写

package common

// 大写的标识符在其他包中可访问
func Add(a int, b int) int {
    return a + b
}

// 小写的标识符只在当前包中可访问
func add(a int, b int) int {
    return a + b
}

包的使用

我们来看一下下图,如果将所有函数都写在一个文件里那么会很难阅读,同时模块划分也会很混乱,所以我们可以把一些工具函数写在其他包中,在需要使用的地方导入包即可。

 我们可以使用这样一个简单的结构来测试

在main中调用common中的Add和db中的Getconn

package db

func Getconn() {
	println("数据库连接")
	println("dbutil函数执行")
}
package aaa

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

main.go

package main

import (
	"fmt"
	"gocode/test_10_2/common"
	"gocode/test_10_2/db"
)

func main() {
	fmt.Println("main函数执行")
	db.Getconn()
	var c int = aaa.Add(1, 5)
	println(c)
	
}

运行输出如下

那同名函数会冲突吗

 

我们在db中也定义一个Add调用,其实也不会冲突,因为需要使用导入的包名作为前缀来调用函数。//在 main 函数中,我们使用 aaa.Add 来调用 Add 函数。这里 aaa 是包名,Add 是函数名。

小结

举报

相关推荐

0 条评论