1,075
社区成员




由七牛云首次提出的Go+填补了国人开发者在数据科学领域的空白。经过一年多时间的打磨,Go+1.0已于10月15日面世。许式伟这样描述设计Go+的初心与核心思想,“我们试图用Go+ 来统一程序员和数据科学家,让他们之间有共同话语,让双方能自然对话”。
目前,Go+1.0已经能够为工程使用,而且语言的使用门槛做了进一步的降低,更接近自然语言,1.0的门槛甚至比Python更低,使得Go+ 更适合STEM教育的场景。
Go+ 的愿景是希望"三位一体",融合工程开发的 Go、数据科学领域的 Python、编程教学领域的 Scratch,以 Python 之形结合 Go 之心,让工程师处理数据不需要学习新的开发语言,让初学者学习编程、开发作品的门槛更低。
(1)下载Go安装包
下载网址:Downloads - go.dev
(2)linux下安装Go
1.把下载的文件拷贝到linux服务器,解压:
tar -C /usr/local -zxvf go1.17.4.linux-amd64.tar.gz
vi /etc/profile
在最后一行添加
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPROXY=https://goproxy.cn,direct
执行下方命令生效
source /etc/profile
执行下方命令验证
go version
如果出现下面版本,证明安装成功
go version go1.17.4 linux/amd64
(1)下载Go+安装包
官方 GitHub 地址:https://github.com/goplus/gop
复制http链接,使用git下载
git clone https://github.com/goplus/gop.git
(2)linux下安装Go+
1.安装
cd gop
./all.bash (windows下执行all.bat)
2. 验证
cd bin/
./gop version
如果出现下面版本,证明安装成功
gop v1.0.32-45-gfc42b40 linux/amd64
三、编译Go+程序验证
1、编写程序
vi hello.go
package main
import "fmt"
func main() {
fmt.Println("Hello Go+")
}
2、执行运行
./gop run test.go
println [x*x for x <- 1:6:2] // output: [1 9 25]
mapData := {"Hi": 1, "Hello": 2, "Go+": 3}
reversedMap := {v: k for k, v <- mapData}
println reversedMap // output: map[1:Hi 2:Hello 3:Go+]
所有go的 packages,甚至是部分cgo的 packages都能被go+导入
import (
"fmt"
"strings"
)
x := strings.NewReplacer("?", "!").Replace("hello, world???")
fmt.Println "x:", x
所有Go+的 packages也能被go程序导入
下面是一个名为foo的Go+的自定义包
package foo
func ReverseMap(m map[string]int) map[int]string {
return {v: k for k, v <- m}
}
可以直接在go程序中使用
package main
import (
"fmt"
"github.com/goplus/tutorial/14-Using-goplus-in-Go/foo"
)
func main() {
rmap := foo.ReverseMap(map[string]int{"Hi": 1, "Hello": 2})
fmt.Println(rmap)
}
按照下面方式编译这个样例
gop install -v ./...
Go支持字节码后端和Go代码生成
gop run # Run a Go+ program
gop install # Build Go+ files and install target to GOBIN
gop build # Build Go+ files
gop test # Test Go+ packages
gop fmt # Format Go+ packages
gop clean # Clean all Go+ auto generated files
gop go # Convert Go+ packages into Go packages
可以使用igop命令生成字节码去执行
igop # Run a Go+ program
var a bigint = 1r << 65 // bigint, large than int64
var b bigrat = 4/5r // bigrat
c := b - 1/3r + 3 * 1/2r // bigrat
println a, b, c
var x *big.Int = 1r << 65 // (1r << 65) is untyped bigint, and can be assigned to *big.Int
var y *big.Rat = 4/5r
println x, y
x := {"Hello": 1, "xsw": 3.4} // map[string]float64
y := {"Hello": 1, "xsw": "Go+"} // map[string]interface{}
z := {"Hello": 1, "xsw": 3} // map[string]int
empty := {} // map[string]interface{}
x := [1, 3.4] // []float64
y := [1] // []int
z := [1+2i, "xsw"] // []interface{}
a := [1, 3.4, 3+4i] // []complex128
b := [5+6i] // []complex128
c := ["xsw", 3] // []interface{}
empty := [] // []interface{}
func plot(fn func(x float64) float64) {
// ...
}
func plot2(fn func(x float64) (float64, float64)) {
// ...
}
plot x => x * x // plot(func(x float64) float64 { return x * x })
plot2 x => (x * x, x + x) // plot2(func(x float64) (float64, float64) { return x * x, x + x })
type Config struct {
Dir string
Level int
}
func foo(conf *Config) {
// ...
}
foo {Dir: "/foo/bar", Level: 1}
也可以在返回值中省略结构体类型
type Result struct {
Text string
}
func foo() *Result {
return {Text: "Hi, Go+"} // return &Result{Text: "Hi, Go+"}
}
a := [x*x for x <- [1, 3, 5, 7, 11]]
b := [x*x for x <- [1, 3, 5, 7, 11], x > 3]
c := [i+v for i, v <- [1, 3, 5, 7, 11], i%2 == 1]
d := [k+","+s for k, s <- {"Hello": "xsw", "Hi": "Go+"}]
arr := [1, 2, 3, 4, 5, 6]
e := [[a, b] for a <- arr, a < b for b <- arr, b > 2]
x := {x: i for i, x <- [1, 3, 5, 7, 11]}
y := {x: i for i, x <- [1, 3, 5, 7, 11], i%2 == 1}
z := {v: k for k, v <- {1: "Hello", 3: "Hi", 5: "xsw", 7: "Go+"}, k > 3}
type student struct {
name string
score int
}
students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}]
unknownScore, ok := {x.score for x <- students, x.name == "Unknown"}
jasonScore := {x.score for x <- students, x.name == "Jason"}
println unknownScore, ok // output: 0 false
println jasonScore // output: 80
type student struct {
name string
score int
}
students := [student{"Ken", 90}, student{"Jason", 80}, student{"Lily", 85}]
hasJason := {for x <- students, x.name == "Jason"} // is any student named Jason?
hasFailed := {for x <- students, x.score < 60} // is any student failed?
sum := 0
for x <- [1, 3, 5, 7, 11, 13, 17], x > 3 {
sum += x
}
start:end:step
)
for i <- :10 {
println i
}
for i := range :10:2 {
println i
}
for i := range 1:10:3 {
println i
}
for range :10 {
println "Range expression"
}
type Foo struct {
}
// Gop_Enum(proc func(val ValType)) or:
// Gop_Enum(proc func(key KeyType, val ValType))
func (p *Foo) Gop_Enum(proc func(key int, val string)) {
// ...
}
foo := &Foo{}
for k, v := range foo {
println k, v
}
for k, v <- foo {
println k, v
}
println {v: k for k, v <- foo}
或者
type FooIter struct {
}
// (Iterator) Next() (val ValType, ok bool) or:
// (Iterator) Next() (key KeyType, val ValType, ok bool)
func (p *FooIter) Next() (key int, val string, ok bool) {
// ...
}
type Foo struct {
}
// Gop_Enum() Iterator
func (p *Foo) Gop_Enum() *FooIter {
// ...
}
foo := &Foo{}
for k, v := range foo {
println k, v
}
for k, v <- foo {
println k, v
}
println {v: k for k, v <- foo}
import "math/big"
type MyBigInt struct {
*big.Int
}
func Int(v *big.Int) MyBigInt {
return MyBigInt{v}
}
func (a MyBigInt) + (b MyBigInt) MyBigInt { // binary operator
return MyBigInt{new(big.Int).Add(a.Int, b.Int)}
}
func (a MyBigInt) += (b MyBigInt) {
a.Int.Add(a.Int, b.Int)
}
func -(a MyBigInt) MyBigInt { // unary operator
return MyBigInt{new(big.Int).Neg(a.Int)}
}
a := Int(1r)
a += Int(2r)
println a + Int(3r)
println -a
expr! // panic if err
expr? // return if err
expr?:defval // use defval if err
具体使用场景
import (
"strconv"
)
func add(x, y string) (int, error) {
return strconv.Atoi(x)? + strconv.Atoi(y)?, nil
}
func addSafe(x, y string) int {
return strconv.Atoi(x)?:0 + strconv.Atoi(y)?:0
}
println `add("100", "23"):`, add("100", "23")!
sum, err := add("10", "abc")
println `add("10", "abc"):`, sum, err
println `addSafe("10", "abc"):`, addSafe("10", "abc")
输出如下
add("100", "23"): 123
add("10", "abc"): 0 strconv.Atoi: parsing "abc": invalid syntax
===> errors stack:
main.add("10", "abc")
/Users/xsw/tutorial/15-ErrWrap/err_wrap.gop:6 strconv.Atoi(y)?
addSafe("10", "abc"): 10
import "gop/ast/goptest"
doc := goptest.New(`... Go+ code ...`)!
println doc.Any().FuncDecl().Name()
#!/usr/bin/env -S gop run
println "Hello, Go+"
println 1r << 129
println 1/3r + 2/7r*2
arr := [1, 3, 5, 7, 11, 13, 17, 19]
println arr
println [x*x for x <- arr, x > 3]
m := {"Hi": 1, "Go+": 2}
println m
println {v: k for k, v <- m}
println [k for k, _ <- m]
println [v for v <- m]