Gox語言默認選用Qlang語法引擎崖疤,Qlang腳本語言又是基于Go語言(Golang)做了一定的改進,數(shù)據(jù)類型基本繼承自Go語言蜕依,數(shù)據(jù)的賦值等操作也基本類似但略加改進和變化桅锄。一個主要的不同是,Gox語言使用動態(tài)類型样眠,與Go語言的區(qū)別主要體現(xiàn)在:
- 變量賦值前無需先進行類型聲明友瘤,例如,下面的都是合法的變量賦值方法檐束,賦值時辫秧,Gox語言會自動確定其類型;另外被丧,使用“=”或“:=”都可以盟戏,其作用是一樣的,“:=”并不像Go語言中一樣表示聲明變量并賦值的意思晚碾,因此抓半,一般建議直接用“=”來進行變量賦值。
a = 1
b = "abc"
- 同一變量可以被先后賦值為不同的類型格嘁,也就意味值在Gox語言中笛求,變量的類型是可變的,這是與Go語言明顯的不同糕簿。
a = 1
a = "list"
a = true
上面給變量a先后賦給整數(shù)探入、字符串和布爾類型等,都是可以的懂诗。
?
大小寫敏感
注意蜂嗽,Gox語言也是大小寫敏感的,各種標識符(包括變量名殃恒、函數(shù)名植旧、結(jié)構(gòu)體名等)大小寫不同的話辱揭,都會被認為是不同的。
?
變量的聲明與賦值
Gox語言中病附,并沒有局部變量聲明问窃,也就是說,如果已經(jīng)存在全局變量a完沪,那么在函數(shù)體或嵌入代碼塊中出現(xiàn)同名的變量域庇,都被認為是對全局變量進行操作,這點要特別注意覆积,全局變量起名要比較慎重听皿,建議末尾加大寫的G(global的意思)表示區(qū)別:
a = 1
fn() {
a = 2
}()
println(a)
其中,fn是Gox語言中定義函數(shù)的關(guān)鍵字宽档,相當于Go語言中的func尉姨,或其他語言中的function。println是Gox語言內(nèi)置的函數(shù)雌贱,作用是輸出信息啊送,與其他語言的println相同偿短。定義好的函數(shù)后直接可以加括號來調(diào)用欣孤,這樣是一個匿名函數(shù)的定義和執(zhí)行的方法。這段代碼運行后將得到下面的結(jié)果:
2
可以看出昔逗,全局變量a在匿名函數(shù)執(zhí)行后降传,值由1變成了2。
而例外的是函數(shù)定義中參數(shù)的名稱會影響這一點勾怒,下面這段代碼婆排,
b = "I'm fine."
fn(b) {
b = "Hi!"
}(b)
println(b)
執(zhí)行結(jié)果是:
I'm fine.
可以清楚地看出,由于這段代碼中定義的匿名函數(shù)需要一個參數(shù)笔链,并且名字與全局變量b的名字相同段只,因此,在這個函數(shù)中鉴扫,對變量b的操作是針對傳入函數(shù)的變量值來操作的赞枕,我們知道,對于傳值的參數(shù)坪创,在函數(shù)內(nèi)對其進行操作不會影響原始的變量本身,因此函數(shù)執(zhí)行后輸出的全局變量b的值仍然沒變柠掂。
另外注意,帶有參數(shù)的匿名函數(shù)的調(diào)用方法,后面的括號中要帶上所需的參數(shù),并且fn的函數(shù)定義中的b與調(diào)用函數(shù)時代入的b表示的是兩個概念,第一個是函數(shù)的形式參數(shù),第二個是指全局變量b手素,不要搞混淆了疹瘦。
布爾類型
布爾類型英語中一般稱作boolean,也常簡稱bool,布爾類型數(shù)據(jù)的取值只有true和false兩個值,分別代表真與假、是或否等對立的概念。布爾類型的數(shù)值或變量經(jīng)常被用于條件判斷分支代碼中利赋。
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函數(shù)也是Gox語言的內(nèi)置函數(shù),與其他語言的printf功能是基本一致拿霉,與Go語言中的printf函數(shù)完全一樣吟秩。因此,其中如果要輸出回車換行符也要用轉(zhuǎn)義字符“\n”绽淘。
這段代碼執(zhí)行后涵防,輸出結(jié)果如下:
λ 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。很多表達式的計算結(jié)果也是bool類型的驮肉,例如“b==c”表示判斷變量b與c中的值是否相等(“==”符號表示判斷其兩邊的變量值是否相等)熏矿,其結(jié)果也是一個bool類型的值已骇,由于b和c中的值并不相等离钝,所以“b == c”的計算結(jié)果是false。因此褪储,b == true這個表達式的結(jié)果就是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纺蛆。
整數(shù)類型
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)
這段代碼的執(zhí)行結(jié)果是:
λ gox -gopath test
25
int, 19
int
int
int
int, 150
c1: 60, c2: 22, int
可以清晰地看出吐葵,整數(shù)的運算,結(jié)果一般來說還是證書桥氏。并且整數(shù)都是64位的温峭。另外,運算符++字支、--凤藏、*=,+=也都有效(還有-=堕伪,/=也都可以使用)清笨。
另外,printfln是Gox語言內(nèi)置的函數(shù)刃跛,相當于printf函數(shù)并且會在最后多輸出一個回車換行符抠艾。而“%T”和“%v”是從Go語言中繼承過來的格式符,“%T”表示輸出后面對應變量的類型桨昙,“%v”則是輸出任意變量的字符串表示检号。
Gox語言中也支持int64,uint8蛙酪,rune等Go語言中常見的類型齐苛,在一些函數(shù)調(diào)用中會使用到,需要的時候可以用下述方式轉(zhuǎn)換:
c1 = 19
c2 = int64(c1)
?
浮點數(shù)類型
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")
執(zhí)行結(jié)果為:
λ gox -gopath test
1.32*0.8=1.056
0.99/0.3=3.3000000000000003
需要注意的是桂塞,print也是Gox語言的內(nèi)置函數(shù)凹蜂,功能與其他語言中的print類似,如果要輸出回車換行符阁危,可以用本代碼中所示的兩種方法玛痊,一種是加一個沒有參數(shù)的println函數(shù),另一種是多輸出一個轉(zhuǎn)義符“\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))
}
運行結(jié)果是:
λ 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函數(shù)可以查看變量的名稱擂煞、類型和值,在調(diào)試代碼的時候比較方便趴乡,但注意函數(shù)的參數(shù)要求傳入變量名稱对省,是個字符串,要加引號晾捏;
- pl函數(shù)與printfln作用相同蒿涎,只是個簡寫;
- 字符串加法的意義則是兩個字符串連接(或者叫合并)起來惦辛;
- 與Go語言相同劳秋,對于UTF-8編碼的字符,轉(zhuǎn)成[]rune類型才可以處理正確,因此俗批,要想正確地遍歷utf-8字符串俗或,需要轉(zhuǎn)換成[]rune類型(rune類型本質(zhì)上是int32類型);
?
空類型nil
Gox語言中的空類型實際上用到的場景沒有那么多岁忘,主要用途有以下幾種情況:
- 用于事先聲明一個變量辛慰,聲明的時候可能無法確定類型或取值;例如定義一個在后面賦值的全局變量時干像;但實際上Gox語言為了這個目的帅腌,可以直接一個變量名就表示聲明一個變量;
- 用于調(diào)用Go語言庫中會返回nil類型的函數(shù)時進行交互和判斷麻汰,例如常見的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())
}
執(zhí)行結(jié)果為:
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函數(shù)就是會返回error類型值得函數(shù),當傳入?yún)?shù)的字符串無法被轉(zhuǎn)換為整數(shù)類型時五鲫,返回的第二個值(error類型)將不是nil溺职,而可以正常轉(zhuǎn)換時,將返回nil值位喂。
另外注意浪耘,Gox語言中,如果沒有定義一個變量就直接被引用(而不是賦值)塑崖,會得到undefined這個值七冲,與Javascript語言有些類似。在Go語言中规婆,這樣的用法將產(chǎn)生panic澜躺。當然,條件判斷的時候也可用
if a == undefined {...}
來進行判斷抒蚜。對于數(shù)組和映射(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")
}
運行結(jié)果是:
λ gox -gopath test
v1: "1"
v2: "1"
v3: 0
v3 is undefined
可以看出undefined的使用方法和其輸出時的顯示值。
?
數(shù)據(jù)類型的轉(zhuǎn)換
Gox語言中可以使用int(a)削锰、string(s)等與Go語言中類似的方式進行數(shù)據(jù)類型轉(zhuǎn)換通铲,某些不能直接進行類型轉(zhuǎn)換的,需要用一些其他函數(shù)來執(zhí)行轉(zhuǎn)換動作器贩。另外,可以用內(nèi)置函數(shù)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)
運行結(jié)果為:
λ 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