go语言学习笔记(3)库源码文件

427 阅读2分钟
库源码文件
1.库源码文件与命令源码文件的不同之处
库源码文件不能被直接运行,它仅用于存放程序实体,程序实体指的是变量、常量、函数、结构体、和接口的统称。

2.怎样把命令源码文件中的代码拆分到其他源码文件?
先举一个简单的例子
demo.go

package main

import (
"flag"
)

var (
name string
)

func init() {
flag.StringVar(&name, "name", "every one", "enter name to say hello")
}

func main() {
flag.Parse()
hello(name)
}

demo1.go

package main

import "fmt"

func hello(name string) {
fmt.Printf("Hello ,%s!", name)
}

将这两个文件放在同一目录下,并都声明为同一代码包 main,因为同一目录下的源码文件都要被声明为属于同一个代码包,同时如果目录下有一个命令源码文件,为了让同一个目录下的文件都通过编译,其他文件都要声明属于main包。

结果展示:
命令:go run demo.go demo1.go

结果:Hello ,every one!
或者
命令:go build learnGo/libray_source_file
libray_source_file.exe

结果:Hello ,every one!

例子二
demo.go

package main

import (
"flag"
"learnGo/libray_source_file/demo1"
)

var (
name string
)

func init() {
flag.StringVar(&name, "name", "every one", "enter name to say hello")
}

func main() {
flag.Parse()
demo.Hello(name)
}

demo1.go

package demo

import "fmt"

func Hello(name string) { //首字母大写代表公共方法,小写代表私有方法
fmt.Printf("Hello ,%s!", name)
}

此时两者未放到同一文件夹下,并且demo1声明了自己的包。注意点:
导入包时导入的是该包所在目录相对于src目录的相对路径,但是使用时要用包名为限定符,例如上面的例子用的demo.Hello()而不是demo1.Hello()


2.代码包声明基本规则

(1)同目录下的源文件包声明语句要一致。也就是说,他们要同属于一个代码包。如果,目录中有命令源码文件,name其他种类的源码文件也要属于main包
(2)源码文件声明的代码包的名字可以与父目录名字不一样。但是在构建代码包时生成的结果文件的名称与父目录名字相同。

3.通过internal实现第三种访问权限,模块级私有
通过internal可以将package中大写的函数或者变量名变为其它package不可访问。
具体做法,先定义一个internal package将这些函数变量放在internal package下,这样这些函数方法只能被internal所在的目录的父目录中的package访问。
例如:
  • /a/b/c/internal/d/e/f 可以被/a/b/c import, 不能被 /a/b/g import.
  • $GOROOT/src/pkg/internal/xxx只可以被标准库import ($GOROOT/src/).
  • $GOROOT/src/pkg/net/http/internal 只可以被 net/http 和 net/http/* import.
  • $GOPATH/src/mypkg/internal/foo 只能被$GOPATH/src/mypkg import.
具体实现示例可见:github.com/GodShuning/…下的learn_internal文件

以上是通过internal实现exported类型私有化,还可以通过 go:linkname这个指令实现unexported公有化。