在Go项目中,有一种常见的方法可以添加元数据吗?

huangapple go评论90阅读模式
英文:

Is there a common way to add metadata to a Go project?

问题

在Go语言中,没有像Node.js中的package.json文件那样直接存储模块的元数据。不过,你可以使用Go的模块管理工具来管理模块的元数据。

Go语言的模块管理工具是go.mod文件,它用于定义和管理模块的依赖关系。在go.mod文件中,你可以指定模块的名称、版本以及其他相关信息。

要存储Go模块的作者信息,你可以在go.mod文件中添加一个注释行来记录作者信息。例如:

module example.com/mymodule

// Authors: John Doe, Jane Smith

这样,你就可以在go.mod文件中记录模块的作者信息了。当然,你也可以根据自己的需求定义其他的元数据字段。

需要注意的是,go.mod文件主要用于管理模块的依赖关系,而不是存储模块的详细元数据。如果你需要更复杂的元数据管理,可以考虑使用其他方式,比如在代码中定义一个结构体来存储模块的元数据,并在适当的地方使用该结构体来获取和处理元数据。

英文:

In Node.js, there is a package.json file which contains several metadata on a module, such as its name, its version, its author(s), …

How do you do this in Go?

E.g., I would like to store the authors of a Go module somewhere with the code. Is there a common way of how to do this?

答案1

得分: 7

如果一个Go包有广泛的文档,按照惯例应该将其放在自己的文件doc.go中。

引用博客文章Godoc: documenting Go code中的内容:

> 对于需要大量介绍性文档的包,该包使用另一种约定:将包注释放在自己的文件doc.go中,该文件仅包含这些注释和一个包子句。

您可以在包文档本身中放置任何元数据。

如果您希望这些“元数据”也可以从代码中访问,可以将它们存储在常量中,例如:

const (
    Author      = "Joe Big"
    Version     = "0.1.2.3"
    ReleaseDate = "2015-11-08"
)

请注意,导出的常量也将包含在godoc中,除了它们也可以从代码中访问。

您还可以对这些行进行注释,注释也将包含在godoc中。这些注释可以明确说明它们的含义,例如:

const (
    Author      = "Joe Big"    // 包作者:名字 - 姓氏
    Version     = "0.1.2.3"    // 包版本:主版本.次版本.维护版本.修订版本
    ReleaseDate = "2015-11-08" // 发布日期:年-月-日
)

元数据的元数据

如果您包含一个与日期或时间相关的常量(例如我的示例中的ReleaseDate),通常还可以提供一个布局,该布局可由time.Parse()函数用于将您的string日期/时间转换为time.Time的值。对于上面的示例,它可能如下所示:

const ReleaseDateLayout = "2006-01-02" // 发布日期布局(用于time.Parse())

使用此布局,可以获取time.Time

releaseDate, err := time.Parse(ReleaseDateLayout, ReleaseDate)

另一种选择是提供导出的实用函数,用于处理元数据并提供有关它们的其他信息或以另一种格式呈现它们。例如:

// GetReleaseDate将发布日期作为time.Time值返回。
func GetReleaseDate() time.Time {
	t, err := time.Parse(ReleaseDateLayout, ReleaseDate)
	if err != nil {
		panic(err)
	}
	return t
}

还有一个用于Version的函数:

// GetVersion将Version的部分作为切片返回:
//     {major, minor, maintenance, revision}
func GetVersion() []int {
	vs := []int{}
	for _, s := range strings.Split(Version, ".") {
		if v, err := strconv.Atoi(s); err != nil {
			panic(err)
		} else {
			vs = append(vs, v)
		}
	}
	return vs
}

私有元数据

这些常量是导出的,因此可以从导入和使用它的其他包中访问它们。如果您不希望如此,只需以小写字母开头,它们将无法从“外部”访问(它们不会被导出),例如:

// 此常量将不会出现在godoc中,并且无法从其他包中访问
const codeReviewer = "Jane Small" // 最后的代码审查人员:名字 - 姓氏
英文:

If a Go package has extensive documentation, by convention it should be placed in its own file, doc.go.

Quoting from blog post Godoc: documenting Go code:

> That package uses another convention for packages that need large amounts of introductory documentation: the package comment is placed in its own file, doc.go, which contains only those comments and a package clause.

You may place any metadata in the package doc itself.

If you want these "metadata" to also be available from code, you may store them in constants, e.g.:

const (
    Author      = "Joe Big"
    Version     = "0.1.2.3"
    ReleaseDate = "2015-11-08"
)

Note that exported constants will also be included in the godoc, besides them being available from code too.

You may also comment the lines, the comments will also be included in the godoc. These comments can make it obvious what they are, for example:

const (
    Author      = "Joe Big"    // Package author: first name - last name
    Version     = "0.1.2.3"    // Package version: major.minor.maintenance.revision
    ReleaseDate = "2015-11-08" // Release date: year-month-day
)

Metadata of metadata

If you include a date or time related constant (like ReleaseDate in my example), it is often useful to also provide a layout that can be used by the time.Parse() function to convert your string date/time to a value of time.Time. For the above example, it could look like this:

const ReleaseDateLayout = "2006-01-02" // Release date layout (for time.Parse())

Using this layout, obtaining a time.Time:

releaseDate, err := time.Parse(ReleaseDateLayout, ReleaseDate)

Another option is to provide exported utility functions which process the metadata and provide other info about them or present them in another format. For example:

// GetReleaseDate returns the release date as a value of time.Time.
func GetReleaseDate() time.Time {
	t, err := time.Parse(ReleaseDateLayout, ReleaseDate)
	if err != nil {
		panic(err)
	}
	return t
}

And one for the Version:

// GetVersion returns the parts of the Version as a slice:
//     {major, minor, maintenance, revision}
func GetVersion() []int {
	vs := []int{}
	for _, s := range strings.Split(Version, ".") {
		if v, err := strconv.Atoi(s); err != nil {
			panic(err)
		} else {
			vs = append(vs, v)
		}
	}
	return vs
}

Private metadata

These constants are exported, so they can be reached from other packages that import and use this. If you don't want that, just start them with lower case letter and so they will not be reachable from the "outside" (they will not be exported), e.g.:

// This constant will not be in godoc and is unreachable from other packages
const codeReviewer = "Jane Small" // Last code reviewer: first name - last name

huangapple
  • 本文由 发表于 2015年11月9日 01:50:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/33597048.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定