封装被定义为在单个单元下封装数据。它是将代码与其操作的数据绑定在一起的机制。换句话说,封装是一个保护屏障,防止数据被这个屏障之外的代码访问。
在面向对象的语言中,类的变量或数据对任何其他类都是隐藏的,只能通过声明它们的类的任何成员函数来访问。但是 Go 语言不支持类和对象。所以,在 Go 语言中,封装是通过使用包来实现的。 Go 提供了两种不同类型的标识符,即导出的和未导出的标识符。封装是通过从包中导出元素(变量、函数、方法、字段、结构)来实现的,它有助于控制元素(变量、函数、方法、字段、结构)的可见性。如果定义它们的包在您的程序中可用,则这些元素是可见的。
1. 导出的标识符:导出的标识符是从定义它们的包中导出的那些标识符。这些标识符的第一个字母总是大写。这个大写字母表示给定的标识符是导出标识符。导出的标识符始终限于定义它们的包。当您从包中导出指定的标识符时,您只需导出名称而不是该标识符的实现。这种机制也适用于函数、字段、方法和结构。
例子:
// Go program to illustrate
// the concept of encapsulation
// using exported function
package main
import (
"fmt"
"strings"
)
// Main function
func main() {
// Creating a slice of strings
slc := []string{"GeeksforGeeks", "geeks", "gfg"}
// Convert the case of the
// elements of the given slice
// Using ToUpper() function
for x := 0; x < len(slc); x++ {
// Exported Method
res := strings.ToUpper(slc[x])
// Exported Method
fmt.Println(res)
}
}
输出:
GEEKSFORGEEKS
GEEKS
GFG
说明:在上面的例子中,我们通过从字符串包中导出ToUpper()函数,将slc切片的元素大小写转换为大写。
res := strings.ToUpper(slc[x])
这里ToUpper()函数的第一个字母是大写的,表示这个函数是导出函数。如果尝试将ToUpper()函数的大小写改为小写,那么编译器会报错,如下图:
res := strings.toUpper(slc[x])
Output:
./prog.go:22:9: cannot refer to unexported name strings.toUpper
./prog.go:22:9: undefined: strings.toUpper
所以,这个过程(变量、字段、方法、函数、结构的导出)被称为封装。由于封装我们只导出函数不是在我们的程序中的函数的整体定义和ToUpper的定义()函数包字符串包内,因此对于出口ToUpper的()函数的名称,你首先需要进口字符串包在你的程序中。
2.未导出的标识符:未导出的标识符是那些未从任何包中导出的标识符。它们总是小写。如下例所示,加法函数与任何包无关,因此它是一个未导出的函数,该方法的可见性仅限于该程序。
例子:
// Go program to illustrate
// the unexported function
package main
import "fmt"
// The addition function returns
// the sum of the elements
// Unexported function
func addition(val ...int) int {
s := 0
for x := range val {
s += val[x]
}
fmt.Println("Total Sum: ", s)
return s
}
// Main function
func main() {
addition(23, 546, 65, 42, 21, 24, 67)
}
输出:
Total Sum: 788
封装的好处:
- 对用户隐藏实现细节。
- 增加代码的可重用性。
- 它防止用户随意设置函数的变量。它仅由同一包中的函数设置,并且该包的作者确保该函数保持其内部不变量。