Loading

Go语言单词格式转换命令行工具

学习:单词格式转换 | Go 语言编程之旅 (eddycjy.com)

代码参考:go-programming-tour-book/tour: 《Go 语言编程之旅:一起用 Go 做项目》第一章:命令行程序(Command) (github.com)

使用工具cobra:

go get -u github.com/spf13/cobra@v1.0.0

先搭好架子,再具体实现!

接口的应用中也有这种思想,接口相当于先制定标准再具体实现;

搭好架子/制定标准:全局架构清晰;具体实现。

搭好架子

$ tree
.
├── cmd
│   ├── root.go
│   └── word.go
├── main.go

cmd/word.go,用于单词格式转换的子命令 word 的简单设置

var wordCmd = &cobra.Command{
	Use:   "word",   								// 子命令的命令标识。
	Short: "单词格式转换", 						// 简短说明,在 help 输出的帮助信息中展示。
	Long:  "支持多种单词格式转换",     // 完整说明,在 help 输出的帮助信息中展示。
	Run: func(cmd *cobra.Command, args []string) {}, // 具体实现Todo;
}

func init() {}

cmd/root.go,用于创建根命令,将子命令加入根命令中

var rootCmd = &cobra.Command{} // 新建的空Command

func Execute() error {
	return rootCmd.Execute() // 执行设置的命令;
}

func init() { // init在main函数之间执行;在import此包的变量,常量后,立即执行;
	rootCmd.AddCommand((wordCmd)) // 将创建的子命令加入rootCmd
}
  • 关于init函数:

main包中导入cmd并使用cmd包:

import (
	"log"
	"github.com/KpiHang/tour/cmd"
)

var name string

func main() {
	err := cmd.Execute()
	if err != nil {
		log.Fatalf("cmd.Execute err : %v", err)
	}
}

详细设置word子命令

此步骤还不包括,功能具体的功能实现;

cmd/word.go:

package cmd

import (
	"log"
	"strings"

	"github.com/KpiHang/tour/internal/word"
	"github.com/spf13/cobra"
)

// 用于单词格式转换的子命令 word 的设置

const (
	ModeUpper                      = iota + 1 // 全部转大写;1
	ModeLower                                 // 全部转小写;2
	ModeUnderscoreToUpperCamelCase            // 下划线转大写驼峰;3
	ModeUnderscoreToLowerCamelCase            // 下线线转小写驼峰;4
	ModeCamelCaseToUnderscore                 // 驼峰转下划线;5
)

var str string
var mode int8 // 选择转换模式mode

// Long desc: the long message shown in the 'help <this-command>' output.
var desc = strings.Join([]string{
	"该子命令支持各种单词格式转换,模式如下:",
	"1:全部转大写",
	"2:全部转小写",
	"3:下划线转大写驼峰",
	"4:下划线转小写驼峰",
	"5:驼峰转下划线",
}, "\n")

var wordCmd = &cobra.Command{
	Use:   "word",   // 子命令的命令标识。
	Short: "单词格式转换", // 简短说明,在 help 输出的帮助信息中展示。
	Long:  desc,     // 完整说明,在 help 输出的帮助信息中展示。
	Run: func(cmd *cobra.Command, args []string) {
		var content string
		switch mode {
		case ModeUpper:
			content = word.ToUpper(str)
		case ModeLower:
			content = word.ToLower(str)
		case ModeUnderscoreToUpperCamelCase:
			content = word.UnderscoreToUpperCamelCase(str)
		case ModeUnderscoreToLowerCamelCase:
			content = word.UnderscoreToLowerCamelCase(str)
		case ModeCamelCaseToUnderscore:
			content = word.CamelCaseToUnderscore(str)
		default:
			log.Fatalf("暂不支持该转换模式,请执行 help word 查看帮助文档")
		}

		log.Printf("输出结果: %s", content)
	},
}

func init() {
	wordCmd.Flags().StringVarP(&str, "str", "s", "", "请输入单词内容") // shorthand: 短标识;
	wordCmd.Flags().Int8VarP(&mode, "mode", "m", 0, "请输入单词转换的模式")
	// 在 VarP 系列的方法中,第一个参数为需绑定的变量、第二个参数为接收该参数的完整的命令标志,第三个参数为对应的短标识,第四个参数为默认值,第五个参数为使用说明。
}

  • 因为,word子命令需要两个参数:

    1. -m, --mode int8 请输入单词转换的模式
    2. -s, --str string 请输入单词内容
  • 所以,要把这两个参数,绑定到两个变量,来使用:

    	wordCmd.Flags().StringVarP(&str, "str", "s", "", "请输入单词内容") // shorthand: 短标识;
    	wordCmd.Flags().Int8VarP(&mode, "mode", "m", 0, "请输入单词转换的模式")
    
    • 第一个参数为需绑定的变量
    • 第二个参数为接收该参数的完整的命令标志
    • 第三个参数为对应的短标识
    • 第四个参数为默认值
    • 第五个参数为使用说明
  • 设置功能:

    const (
    	ModeUpper                      = iota + 1 // 全部转大写;1
    	ModeLower                                 // 全部转小写;2
    	ModeUnderscoreToUpperCamelCase            // 下划线转大写驼峰;3
    	ModeUnderscoreToLowerCamelCase            // 下线线转小写驼峰;4
    	ModeCamelCaseToUnderscore                 // 驼峰转下划线;5
    )
    
    
    		var content string
    		switch mode {
    		case ModeUpper:
    			content = word.ToUpper(str)
    		case ModeLower:
    			content = word.ToLower(str)
    		case ModeUnderscoreToUpperCamelCase:
    			content = word.UnderscoreToUpperCamelCase(str)
    		case ModeUnderscoreToLowerCamelCase:
    			content = word.UnderscoreToLowerCamelCase(str)
    		case ModeCamelCaseToUnderscore:
    			content = word.CamelCaseToUnderscore(str)
    		default:
    			log.Fatalf("暂不支持该转换模式,请执行 help word 查看帮助文档")
    		}
    

功能具体实现

新增加internal目录:

$ tree
.
├── cmd
│   ├── root.go
│   └── word.go
├── internal
│   └── word
│       └── word.go
├── main.go

internal包,Go中命名为internal的package或者目录,两点需要注意:

  1. 只有直接父级package,以及父级package的子孙package可以访问,其他的都不行,再往上的祖先package也不行。
  2. 父级package也只能访问internal package使用大写暴露出的内容,小写的不行。

在项目中不被复用,也不能被其他项目导入,仅被本项目内部使用的代码包即私有的代码包都应该放在internal文件夹下。该文件夹下的所有包及相应文件都有一个项目保护级别,即其他项目是不能导入这些包的,仅仅是该项目内部使用。

internal/word/word.go,功能的具体实现:

package word

import (
	"strings"
	"unicode"

	"golang.org/x/text/cases"
	"golang.org/x/text/language"
)

// 单词全部转为小写。
func ToLower(s string) string {
	return strings.ToLower(s)
}

// 单词全部转为大写。
func ToUpper(s string) string {
	return strings.ToUpper(s)
}

// 下划线单词转为大写驼峰。
func UnderscoreToUpperCamelCase(s string) string {
	s = strings.Replace(s, "_", " ", -1)    // 将下划线替换为空格字符
	s = cases.Title(language.Und).String(s) // 将其所有字符修改为其对应的首字母大写的格式 strings.Title go1.18中被遗弃;
	return strings.Replace(s, " ", "", -1)  // 最后将先前的空格字符替换为空
}

// 下划线单词转为小写驼峰。
func UnderscoreToLowerCamelCase(s string) string {
	s = UnderscoreToUpperCamelCase(s)                  // 主体逻辑可以直接复用大写驼峰的转换方法
	return string(unicode.ToLower(rune(s[0]))) + s[1:] // 然后只需要对其首字母进行处理就好了
}

// 驼峰转下划线 eg AppStore --> app_store
func CamelCaseToUnderscore(s string) string {
	var output []rune // rune代表一个utf-8字符
	for i, r := range s {
		if i == 0 {
			output = append(output, unicode.ToLower(r))
			continue
		}
		if unicode.IsUpper(r) {
			output = append(output, '_')
		}
		output = append(output, unicode.ToLower(r))
	}
	return string(output)
}
  • 注意Go 1.18以后,strings.Title()方法被遗弃了,用cases包代替:

    	s = cases.Title(language.Und).String(s) // 将其所有字符修改为其对应的首字母大写的格式 
    
posted @ 2022-11-17 19:28  鲸波行者、苇一航  阅读(145)  评论(0编辑  收藏  举报