TOC

七牛云 Go+

Go+ LOGO

今天得知七牛设计了一门语言 Go+,Go Plus,gop(有点像“狗屁” -_-|||),而且马上要发 1.0 版本了。

Qiniu
QiniuDoll
七牛好酷!
不管现在做的怎么样,这么正式的投入时间精力来设计一门语言,就是很屌。

Go+

仓库:goplus/gop Stars License

项目的设计目标是使 Golang 能够灵活应用于科学计算领域,取代 Python 的地位。

就目前的了解来说,Go+ 和 Go 最大的区别就是代码不需要封装到函数中,就像解释型语言一样。

println("TEST")

如果就只是这样,那没啥神奇的,做个封装就行了。
但据 GitHub 仓库 README 的介绍,Go+ 有两个后端:一个是将 gop 代码生成字节码(字节码模式当然就无法兼容 CGO 了),一个是转 go 代码。
这么看的话,这个字节码后端,对 Go 做了更多事情。

根据网络上的资料:

  1. 支持混合切片,比如 [1, "a"], Go 的设计是数组和切片都有固定类型,有一种变通的方法就是用空 interface
    根据下面的分析:gop 果然就是采用 []interface{} 的形式。
  2. 实现了 Python 的列表解析式 [i**2 for i <- aSlice]

可能目前看起来还不是很牛逼,会招来一些喷子,但是我觉得这个方向很有搞头,如果在七牛内部科学计算方向得到应用,然后不断改进,有机会成为一个了不起的项目。

安装

git clone https://github.com/goplus/gop.git
git clone git@github.com:goplus/igop.git

cd gop
bash all.bash
# go build cmd/gop/main.go -o gop
# sudo mv gop /usr/local/bin/

cd ../igop
go install -tags yaegi -v ./...

gop run 直接执行

/tmp/test.gop:

println "hello world"

a := [1, "a"]
printf("%#v\n", a)

b := [1, 2, 3]
printf "%#v\n", b

c := [i*2 for i <- b]
printf("%#v\n", c)
export PATH=$PATH:$GOPATH/bin && gop run /tmp/test.gop
hello world
[]interface {}{1, "a"}
[]int{1, 2, 3}
[]int{2, 4, 6}

gop go 转换成 go 代码

由于只能转换 go 包,所以我将 /tmp/test.gop 转换成包的形式 /tmp/test,然后:

export PATH=$PATH:$GOPATH/bin && gop go .
GenGoPkg .
-: no required module provides package github.com/goplus/gop/builtin; to add it:
        go get github.com/goplus/gop/builtin
2021/10/14 13:36:09 total 1 errors
total 1 errors

$ go get github.com/goplus/gop/builtin
go: downloading github.com/goplus/gop v1.0.21
go get: added github.com/goplus/gop v1.0.21

$ export PATH=$PATH:$GOPATH/bin && gop go .
GenGoPkg .

$ ls
go.mod  gop_autogen.go  go.sum  main.gop

$ cat gop_autogen.go
package main

import fmt "fmt"

func main() {
//line /tmp/test/main.gop:1
        fmt.Println("hello world")
//line /tmp/test/main.gop:3
        a := []interface {
        }{1, "a"}
//line /tmp/test/main.gop:4
        fmt.Printf("%#v\n", a)
//line /tmp/test/main.gop:6
        b := []int{1, 2, 3}
//line /tmp/test/main.gop:7
        fmt.Printf("%#v\n", b)
//line /tmp/test/main.gop:9
        c := func() (_gop_ret []int) {
                for
//line /tmp/test/main.gop:9
                _, i := range b {
//line /tmp/test/main.gop:9
                        _gop_ret = append(_gop_ret, i*2)
                }
//line /tmp/test/main.gop:9
                return
        }()
//line /tmp/test/main.gop:10
        fmt.Printf("%#v\n", c)
}

使用 igop 执行:

export PATH=$PATH:$GOPATH/bin && igop .