Gox语言默认选用Qlang语法引擎,Qlang脚本语言又是基于Go语言(Golang)做了一定的改进,数据类型基本继承自Go语言,数据的赋值等操作也基本类似但略加改进和变化。一个主要的不同是,Gox语言使用动态类型,与Go语言的区别主要体现在:
- 变量赋值前无需先进行类型声明,例如,下面的都是合法的变量赋值方法,赋值时,Gox语言会自动确定其类型;
a = 1
b = "abc"
- 同一变量可以被先后赋值为不同的类型,也就意味值在Gox语言中,变量的类型是可变的,这是与Go语言明显的不同。
a = 1
a = "list"
a = true
上面给变量a先后赋给整数、字符串和布尔类型等,都是可以的。
大小写敏感
注意,Gox语言也是大小写敏感的,各种标识符(包括变量名、函数名、结构体名等)大小写不同的话,都会被认为是不同的。
变量的声明与赋值
Gox语言中,并没有局部变量声明,也就是说,如果已经存在全局变量a,那么在函数体或嵌入代码块中出现同名的变量,都被认为是对全局变量进行操作,这点要特别注意,全局变量起名要比较慎重,建议末尾加大写的G(global的意思)表示区别:
a = 1
fn() {
a = 2
}()
println(a)
其中,fn是Gox语言中定义函数的关键字,相当于Go语言中的func,或其他语言中的function。println是Gox语言内置的函数,作用是输出信息,与其他语言的println相同。定义好的函数后直接可以加括号来调用,这样是一个匿名函数的定义和执行的方法。这段代码运行后将得到下面的结果:
2
可以看出,全局变量a在匿名函数执行后,值由1变成了2。
而例外的是函数定义中参数的名称会影响这一点,下面这段代码,
b = "I'm fine."
fn(b) {
b = "Hi!"
}(b)
println(b)
执行结果是:
I'm fine.
可以清楚地看出,由于这段代码中定义的匿名函数需要一个参数,并且名字与全局变量b的名字相同,因此,在这个函数中,对变量b的操作是针对传入函数的变量值来操作的,我们知道,对于传值的参数,在函数内对其进行操作不会影响原始的变量本身,因此函数执行后输出的全局变量b的值仍然没变。
另外注意,带有参数的匿名函数的调用方法,后面的括号中要带上所需的参数,并且fn的函数定义中的b与调用函数时代入的b表示的是两个概念,第一个是函数的形式参数,第二个是指全局变量b,不要搞混淆了。
布尔类型
布尔类型英语中一般称作boolean,也常简称bool,布尔类型数据的取值只有true和false两个值,分别代表真与假、是或否等对立的概念。布尔类型的数值或变量经常被用于条件判断分支代码中。
b = true
printf("[%T] %v\n", b, b)
c = false
printf("[%T] %v\n", c, c)
printf("!b = %v\n", !b)
printf("b == c: %v\n", b == c)
printf("1 > 14: %v\n", 1 > 14)
printf("b == true: %v\n", b == true)
printf("b && c: %v\n", b && c)
printf("b || c: %v\n", b || c)
上面这段代码中,printf函数也是Gox语言的内置函数,与其他语言的printf功能是基本一致,与Go语言中的printf函数完全一样。因此,其中如果要输出回车换行符也要用转义字符“\n”。
这段代码执行后,输出结果如下:
λ gox -gopath test
[bool] true
[bool] false
!b = false
b == c: false
1 > 14: false
b == true: true
b && c: false
b || c: true
其中,可以看出,变量a的值是true,变量b的值是false,“!”是取反(也叫“非”)操作符,如果是false取反则是true,true的取反为false。很多表达式的计算结果也是bool类型的,例如“b==c”表示判断变量b与c中的值是否相等(“==”符号表示判断其两边的变量值是否相等),其结果也是一个bool类型的值,由于b和c中的值并不相等,所以“b == c”的计算结果是false。因此,b == true这个表达式的结果就是true了,因为b的值就是true。“&&”和“||”表示“逻辑与”和“逻辑或”,这与很多其他语言也是一致的,true && true 还是 true,true && false 是 false,false && true 还是 false,false && false 也是 false;而true || true 是 true,true || false 还是 false,false || true 也是 true,false || false 则是 false。
整数类型
c1 = 19
c2 = 18
println(c1 + c2/3)
printfln("%T, %v", c1, c1)
printfln("%T", c1+c2)
printfln("%T", c2/3)
printfln("%T", c1+c2/3)
printfln("%T, %v", (c1+c2/3)*6, (c1+c2/3)*6)
c1++
c1 *= 3
c2 += 5
c2--
printfln("c1: %v, c2: %v, %T", c1, c2, c1)
这段代码的执行结果是:
λ gox -gopath test
25
int, 19
int
int
int
int, 150
c1: 60, c2: 22, int
可以清晰地看出,整数的运算,结果一般来说还是证书。并且整数都是64位的。另外,运算符++、--、*=,+=也都有效(还有-=,/=也都可以使用)。
另外,printfln是Gox语言内置的函数,相当于printf函数并且会在最后多输出一个回车换行符。而“%T”和“%v”是从Go语言中继承过来的格式符,“%T”表示输出后面对应变量的类型,“%v”则是输出任意变量的字符串表示。
Gox语言中也支持int64,uint8,rune等Go语言中常见的类型,在一些函数调用中会使用到,需要的时候可以用下述方式转换:
c1 = 19
c2 = int64(c1)
浮点数类型
f1 = 1.32
previus_f1 = f1
f1 = f1 * 0.8
print(previus_f1, "*", 0.8, "=", f1)
println()
f2 = 0.99
f2 /= 0.3
print(0.99, "/", 0.3, "=", f2, "\n")
执行结果为:
λ gox -gopath test
1.32*0.8=1.056
0.99/0.3=3.3000000000000003
需要注意的是,print也是Gox语言的内置函数,功能与其他语言中的print类似,如果要输出回车换行符,可以用本代码中所示的两种方法,一种是加一个没有参数的println函数,另一种是多输出一个转义符“\n”。
字符串类型
下面是一些字符串赋值与操作的例子:
s1 = "abc"
s2 = s1 + "3"
pv("s2")
println(s1, "+", "3", "=", s2)
s5 = "上善若水"
pv("s5")
s6 = []byte(s5)
println(s6)
t = rune(5)
pv("t")
s7 = []rune("上善若水")
pv("s7")
pl("s5[1:2] = %#v", s5[1:2])
pl("s6[1:2] = %#v", s6[1:2])
pl("s7[1:2] = %#v", s7[1:2])
pl("string(s7[1:3]) = %#v", string(s7[1:3]))
pl("string([]byte(string(s7[1:3]))) = %#v", string([]byte(string(s7[1:3]))))
pl("%c", s5[1])
pl("%c", s6[1])
pl("%c", s7[1])
pl("%T, %#v", s5[1], s5[1])
pl("%T, %#v", s6[1], s6[1])
pl("%T, %#v", s7[1], s7[1])
for i = 0; i < len(s5); i++ {
pl("%v: %v", i, s5[i])
}
for v = range s7 {
pl("%#T, %v", byte(v), byte(v))
}
运行结果是:
λ gox -gopath test
s2(string): abc3
abc + 3 = abc3
s5(string): 上善若水
[228 184 138 229 150 132 232 139 165 230 176 180]
t(int32): 5
s7([]int32): [19978 21892 33509 27700]
s5[1:2] = "\xb8"
s6[1:2] = []byte{0xb8}
s7[1:2] = []int32{21892}
string(s7[1:3]) = "善若"
string([]byte(string(s7[1:3]))) = "善若"
¸
¸
善
int, 184
int, 184
int, 21892
0: 228
1: 184
2: 138
3: 229
4: 150
5: 132
6: 232
7: 139
8: 165
9: 230
10: 176
11: 180
int, 0
int, 1
int, 2
int, 3
这里需要注意的是:
- pv函数可以查看变量的名称、类型和值,在调试代码的时候比较方便,但注意函数的参数要求传入变量名称,是个字符串,要加引号;
- pl函数与printfln作用相同,只是个简写;
- 字符串加法的意义则是两个字符串连接(或者叫合并)起来;
- 与Go语言相同,对于UTF-8编码的字符,转成[]rune类型才可以处理正确,因此,要想正确地遍历utf-8字符串,需要转换成[]rune类型(rune类型本质上是int32类型);
空类型nil
Gox语言中的空类型实际上用到的场景没有那么多,主要用途有以下几种情况:
- 用于事先声明一个变量,声明的时候可能无法确定类型或取值;例如定义一个在后面赋值的全局变量时;但实际上Gox语言为了这个目的,可以直接一个变量名就表示声明一个变量;
- 用于调用Go语言库中会返回nil类型的函数时进行交互和判断,例如常见的error类型;
参看下面的例子:
pv("aaa")
println(aaa)
aaa = 18
pv("aaa")
println("aaa")
b = nil
pv("b")
println(b)
println("------")
c, errT = tk.StrToInt("12ab")
if errT != nil {
println("Error:", errT.Error())
}
pv("c")
pv("errT")
c, errT = tk.StrToInt("123")
pv("c")
pv("errT")
if errT != nil {
println("Error:", errT.Error())
}
执行结果为:
aaa(spec.undefinedType): undefined
undefined
aaa(int): 18
aaa
b(<nil>): <nil>
<nil>
------
Error: strconv.ParseInt: parsing "12ab": invalid syntax
c(int): 0
errT(*strconv.NumError): strconv.ParseInt: parsing "12ab": invalid syntax
c(int): 123
errT(<nil>): <nil>
代码中的tk.StrToInt函数就是会返回error类型值得函数,当传入参数的字符串无法被转换为整数类型时,返回的第二个值(error类型)将不是nil,而可以正常转换时,将返回nil值。
另外注意,Gox语言中,如果没有定义一个变量就直接被引用(而不是赋值),会得到undefined这个值,与Javascript语言有些类似。在Go语言中,这样的用法将产生panic。当然,条件判断的时候也可用
if a == undefined {...}
来进行判断。对于数组和映射(map)中也是用undefined来确定其中是否有所需索引的值和键值的,例如:
m = map[string]string{"a": "1", "b": "ABC"}
v1 = m["a"]
pl("v1: %#v", v1)
v2 = m.a
pl("v2: %#v", v2)
v3 = m["c"]
pl("v3: %#v", v3)
if v3 == undefined {
pln("v3 is undefined")
}
运行结果是:
λ gox -gopath test
v1: "1"
v2: "1"
v3: 0
v3 is undefined
可以看出undefined的使用方法和其输出时的显示值。
数据类型的转换
Gox语言中可以使用int(a)、string(s)等与Go语言中类似的方式进行数据类型转换,某些不能直接进行类型转换的,需要用一些其他函数来执行转换动作。另外,可以用内置函数type来获取某个变量的类型。下面的例子代码展示了这些用法。
a = 1
b = int64(2)
println("type of a is:", type(a))
println("type of b is:", type(b))
println("a + b =", a+b)
printfln("a + b = %#v", a+b)
a1 = tk.IntToStr(a)
b1 = tk.IntToStr(b)
printfln("type of a1 is: %T", a1)
printfln("value of a1 is: %v", a1)
printfln("internal value of a1 is: %#v", a1)
println("a1 + b1 =", a1+b1)
printfln("a1 + b1 = %#v", a1+b1)
a2 = tk.StrToFloat64WithDefaultValue(a1, 0)
b2 = tk.StrToFloat64WithDefaultValue(b1, 0)
printfln("a2 + b2 = %#v", a2+b2)
printfln("type of a2 + b2 is: %T", a2+b2)
运行结果为:
λ gox -gopath test
type of a is: int
type of b is: int64
a + b = 3
a + b = 3
type of a1 is: string
value of a1 is: 1
internal value of a1 is: "1"
a1 + b1 = 12
a1 + b1 = "12"
a2 + b2 = 3
type of a2 + b2 is: float64
有疑问加站长微信联系(非本文作者)