golang package 是什么意思?一份来自初学者的golang package体验指南

如果你有其他语言的基础,可见性应该很好理解。
java的可见性是通过public private来描述的。
python的可见性是通过_some_var下划线来约定的。

本文翻译自:https://www.callicoder.com/golang-packages/
为啥老外能把事情说的这么明白。。。
golang中任何一个文件都要属于一个package
多个文件可以属于同一个package
同一个package中可以有两个同名的函数吗?
如何导入一个package
如何导入一个第三方的package
一个包里面含有另一个包可以吗?
包和目录有什么联系吗?
一个包可以有多个init吗?

函数可以用来复用代码。包也是复用代码的一种方式。package把你的go源码文件组织成为一个单个的单元,让你的代码更加模块化,可重用。

在这篇文章中将要学习如何组织代码成为package,如何导入一个包,如何导出包里面的函数,type,或者变量,如何导入第三方包。

Let’s get started!

In the most basic terms, A package is nothing but a directory inside your Go workspace containing one or more Go source files, or other Go packages.

在这里插入图片描述

Every Go source file belongs to a package. 使用下面的语法声明一个源文件属于一个包

package <packagename>

这行代码需要写在源文件的开头。定义在源文件里面的函数,types,变量都会成为这个包的一部分。

You can choose to export a member defined in your package to outside packages, or keep them private to the same package. Other packages can import and reuse the functions or types that are exported from your package.

让我们看一个例子:

import "fmt"

fmt is a core library package that contains functionalities related to formatting and printing output or reading input from various I/O sources. It exports functions like Println(), Printf(), Scanf() etc, for other packages to reuse.

使用package组织代码有如下好处:

  • It reduces naming conflicts. You can have the same function names in different packages. This keeps our function names short and concise.

  • It organizes related code together so that it is easier to find the code you want to reuse.

  • It speeds up the compilation process by only requiring recompilation of smaller parts of the program that has actually changed. Although we use the fmt package, we don’t need to recompile it every time we change our program.

main package和main函数

Go programs start running in the main package. It is a special package that is used with programs that are meant to be executable.

By convention, Executable programs (the ones with the main package) are called Commands. Others are called simply Packages.

The main() function is a special function that is the entry point of an executable program. Let’s see an example of an executable program in Go -

// Package declaration
package main

// Importing packages
import (
	"fmt"
	"time"
	"math"
    "math/rand"
)

func main() {
	// Finding the Max of two numbers
	fmt.Println(math.Max(73.15, 92.46))
	
	// Calculate the square root of a number
	fmt.Println(math.Sqrt(225))

	// Printing the value of `𝜋`
	fmt.Println(math.Pi)

	// Epoch time in milliseconds
	epoch := time.Now().Unix()
	fmt.Println(epoch)

	// Generating a random integer between 0 to 100
	rand.Seed(epoch)
	fmt.Println(rand.Intn(100))
}

导入包

there are two ways to import packages

// Multiple import statements
import "fmt"
import "time"
import "math"
import "math/rand"
// Factored import statements
import (
	"fmt"
	"time"
	"math"
    "math/rand"
)

Go’s convention is that - the package name is the same as the last element of the import path. For example, the name of the package imported as math/rand is rand. It is imported with path math/rand because It is nested inside the math package as a subdirectory.

导出或者不导出

Anything只要是以大写字母开头的,都是可以导出的,outside a package可见。
不是以大写字母开头的,只能在相同的包名内可见

当你import了一个包,你只能访问它的导出的命名
在这里插入图片描述

Creating and managing custom Packages

mdkir packer
cd packer
go mod init github.com/callicoder/packer

目录结构如下图
在这里插入图片描述

源码如下
numbers/prime.go

package numbers

import "math"

// Checks if a number is prime or not
func IsPrime(num int) bool {
    for i := 2; i <= int(math.Floor(math.Sqrt(float64(num)))); i++ {
        if num%i == 0 {
            return false
        }
	}
    return num > 1
}

strings/reverse.go

package strings

// Reverses a string
/*
	Since strings in Go are immutable, we first convert the string to a mutable array of runes ([]rune), 
	perform the reverse operation on that, and then re-cast to a string.
*/
func Reverse(s string) string {
	runes := []rune(s)
	reversedRunes := reverseRunes(runes)
	return string(reversedRunes)
}

strings/reverse_runes.go

package strings

// Reverses an array of runes
// This function is not exported (It is only visible inside the `strings` package)
func reverseRunes(r []rune) []rune {
	for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
		r[i], r[j] = r[j], r[i]
	}
	return r
}

//下面用到了在一个包目录下含有另一个包

strings/greeting/texts.go (Nested package)

// Nested Package
package greeting

// Exported
const  (
	WelcomeText = "Hello, World to Golang"
    MorningText = "Good Morning"
	EveningText = "Good Evening"
)

// Not exported (only visible inside the `greeting` package)
var loremIpsumText = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad 
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea 
commodo consequat.`

main.go (The main package: entry point of our program)

package main

import (
	"fmt"
	str "strings" // Package Alias

	"github.com/callicoder/packer/numbers"
	"github.com/callicoder/packer/strings"
	"github.com/callicoder/packer/strings/greeting" // Importing a nested package
)

func main() {
	fmt.Println(numbers.IsPrime(19))

	fmt.Println(greeting.WelcomeText)

	fmt.Println(strings.Reverse("callicoder"))

	fmt.Println(str.Count("Go is Awesome. I love Go", "Go"))
}
# Building the Go module
$ go build
The above command will produce an executable binary. Let’s execute the binary file to run the program:

# Running the executable binary
$ ./packer
true
Hello, World to Golang
redocillac
2

Things to note

  • Import Paths
  • Package Alias
    You can use package alias to resolve conflicts between different packages of the same name, or just to give a short name to the imported package

在这里插入图片描述

  • Nested Package
    You can nest a package inside another. It’s as simple as creating a subdirectory -

在这里插入图片描述

A nested package can be imported similar to a root package. Just provide its path relative to the module’s path github.com/callicoder/packer -

在这里插入图片描述

添加第三方包

Adding 3rd party packages to your project is very easy with Go modules. You can just import the package to any of the source files in your project, and the next time you build/run the project, Go automatically downloads it for you (此处存疑,因为我这里没有自动下载)

手动安装

You can use go get command to download 3rd party packages from remote repositories.

$ go get -u github.com/jinzhu/gorm
The above command fetches the gorm package from Github and adds it as a dependency to your go.mod file.

That’s it. You can now import and use the above package in your program like this -

import "github.com/jinzhu/gorm"

Conclusion

That’s all folks! In this article, you learned how to organize Go code into reusable packages, how to import a package, how to export members of a package, how to create custom packages, and how to install third party packages.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值