[https://bbs.csdn.net/topics/603464006?utm_source=1594742339](“我的Go+语言初体验” | 征文活动进行中......)


一、什么是Go+语言?
Go+ 是七牛云 CEO 许式伟发明的一门可用于工程、STEM 教育和数据科学的编程语言,于 2020 年 7 月正式发布,2021 年 10 月推出 1.0 版本。
关于Go+语言更详细的内容大家可以上官网进行查看,或者在CSDN的Go+社区中查看,官方还有各路达人已经对其进行了详细的说明,这里就不再引述了。本文主要是写一下我对Go+的一些理解和使用Go+进行开发脚本的内容。

二、我对Go+的一些理解
  首先声明,我之前并没有学习过 Go 语言, Go+ 也是这次活动中初次了解,写的个人理解难免会有许多问题之处,还望大家多多理解、支持,对我文中的问题予以指出,共同进步,谢谢。

  一般情况,学习一门新开发的语言,肯定是要通过官网进行学习的,毕竟刚开发出的语言,是没有书籍可供学习的,所以官网就是学习语言的唯一途径。首次访问 Go+ 官网,发现文字都是英文的,就想着找找语言切换,转换成中文来看,可是找来找去,没有找到,竟然没有中文,确实有点出乎我的意料了,毕竟国人开发的语言,没有中文说明,只有英文,确实很难让人理解。可能从作者的角度来看,英文更有利于 Go+ 语言的传播,毕竟英语是世界流通语言,世界上的技术人都可以进行学习,但是现在我们开发所用的语言基本都是外国人开发的,我们国人自己开发的语言是否会有外国人来看,或者去深入了解呢?这可能需要画上一个问号了。

  但是国人就不一样了, 我们现在还没有属于自己的操作系统、芯片,让全世界都使用的编程语言,所以出现了一款国人自己开发的编程语言,而且是功能强大的编程语言,想必肯定有很多人和我一样,对此抱有极大的热情和兴趣,希望它可以发展起来,所以在此希望官方可以将网站改换成中文的,方便国人阅读和学习。当学习和用的人多了,开发出了了不得的东西时,自然会发展越来越快。

  从 Go+ 官网的描述中知道了 Go+ 可以完全兼容 Go ,可以使用Go来进行开发,而 Go+ 的使用基本都是以代码示例的形式来表述的,但是官网中的示例有些少,而现在看到的文章内容又多是以 Go 的形势进行开发的,让人很难去理解 Go+ 的编程思想,也很难区分 Go+ 和 Go 的区别哪里?希望官方可以对此进行一些详细说明,再加之一些代码示例来提现 Go+ 的不同之处,能够让人一眼就理解 Go+ ,并喜欢上这门语言。

三、使用Go+编写Linux脚本
  从官网学习中了解到可以使用 Go+ 程序用作 shell 脚本,这吸引到了我,这样一来就可以使用 Go+ 的强大功能来编写具有强大功能的脚本,一些 shell 脚本无法完成的工作都可以使用 Go+ 来做,想想就很开心,节省了开发时间,早下班呗。

  我使用 Go+ 开发了一个简单的 shell 脚本来进行测试,功能是展示目录结构,仿着 tree 命令来写的,首先看一下运行效果。文件太多,图没有截完。

img

  现在开始写脚本内容,第一行声明,告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
我这里写的和官网示例上不一样,因为我本地的路径和官网不一样,如果按照官网上来写的话,脚本是无法运行的。
#!/root/gop/bin/gop run 
使用 Go 的 flag 模块来获取命令行参数,这里设置了dir参数,用于展示指定路径的目录结构,使用方式 -dir 路径
dirPtr := flag.String("dir", ".", "查看目录路径,默认命令执行的当前路径")
flag.Parse()

使用 ioutil 模块读取指定路径下的文件列表,接下来通过循环的方式打印文件名称
files,_ := ioutil.ReadDir(*dirPtr)
显示的目录下的文件有可能不光是文件,还有文件夹,那么文件夹的内容也需要展示,所以写了一个递归方法,用于递归展示文件,三个参数分别是:目录路径、文件对象、目录层级,目录层级主要用于格式化打印时使用
func PrintFileName(rootpath string, f os.FileInfo, level int) {
    PrintSpace(level)
    println "|__", f.Name()

    if f.IsDir() {
        files,_ := ioutil.ReadDir(rootpath + "/" + f.Name())
        for _,cf := range files {
            if cf.IsDir() {
                PrintFileName(rootpath + "/" + f.Name() + "/", cf, level + 1)
            } else {
                PrintSpace(level + 1)
                println "|__", cf.Name()
            }
        }
    }
}
以下是全部代码
#!/root/gop/bin/gop run
import (
    "flag"
    "io/ioutil"
    "os"
)

func PrintSpace(num int) {
    for i <- :num {
        _ = i
        print "|    "
    }
}

func PrintFileName(rootpath string, f os.FileInfo, level int) {
    PrintSpace(level)
    println "|__", f.Name()

    if f.IsDir() {
        files,_ := ioutil.ReadDir(rootpath + "/" + f.Name())
        for _,cf := range files {
            if cf.IsDir() {
                PrintFileName(rootpath + "/" + f.Name() + "/", cf, level + 1)
            } else {
                PrintSpace(level + 1)
                println "|__", cf.Name()
            }
        }
    }
}

dirPtr := flag.String("dir", ".", "查看目录路径,默认命令执行的当前路径")
flag.Parse()

files,_ := ioutil.ReadDir(*dirPtr)
println *dirPtr
for _,f := range files {
    PrintFileName(*dirPtr, f, 0)
}
  运行脚本时记得给脚本加上执行权限,还需要使用 gop mod init 初始化以下目录,不然脚本无法执行。
  运行示例(我将脚本命名为goptree):./goptree,不加参数,默认执行命令的当前路径

img

  运行示例:./goptree -dir /usr/src,通过 dir 参数指定展示的目录路径

img