Gox語言中的基本數據類型及其轉換-GX2

Gox語言以腳本語言Anko為語法基礎,而Anko語言又是基於Go語言(Golang)做了一定的改進,因此數據類型大致類似於Go語言,數據的賦值等操作也類似但略有不同。下面做一些說明,並用實例來進行驗證。


Gox語言中的基本數據類型及其轉換-GX2


Gox語言中,變量聲明可以使用“var”關鍵字,也可以不用,與JavaScript語言類似,var關鍵字只是用來指定該變量是局部變量。另外變量無需指定類型,並且同一變量可以改變數據類型,也就是說變量可以隨著它其中存放的數值類型而改變自己的類型。看看下面這段代碼:

<code>var a = 1

printfln("[%T] %v", a, a)

b = 1

printfln("[%T] %v", b, b)

a = "abc"

printfln("[%T] %v", a, a)
/<code>


其中,printfln是Gox語言內置的函數,相當於printf函數並且會在最後多輸出一個回車換行符。而“%T”和“%v”是從Go語言中繼承過來的格式符,“%T”表示輸出後面對應變量的類型,“%v”則是輸出任意變量的字符串表示。而這段代碼中,先對變量a用var關鍵字定義並賦值,然後又不用var而直接用等號“=”賦值一個新的變量b,最後又給變量a賦一個字符串類型的值。運行後將得到下面的結果:

Gox語言中的基本數據類型及其轉換-GX2

可以看出,使用關鍵字var與否在這段代碼中對於定義變量並沒有什麼實質影響,因為都是在一個層級的代碼段內。變量a、b都是int64類型,數值都是1,而變量a後來可以被直接賦值為string類型的變量,也就是字符串類型的變量,值為“abc”。這說明Gox語言中變量的類型是可以改變的,這是與Go語言顯著的不同之一。


而這段代碼,

<code>a = 1
func() {
a = 2
}()
println(a)

var a = 1
func() {
a = 2
}()
println(a)

a = 1
func() {
var a = 2
}()
println(a)

var a = 1
func() {
var a = 2
}()
println(a)
/<code>

執行結果是:

Gox語言中的基本數據類型及其轉換-GX2

可以清楚地看出使用var關鍵字定義局部變量的效果,前兩個函數中沒有使用var關鍵字,導致對變量a的修改其實是修改了全局變量a,而後面兩個函數都是用var創建了局部a,它的值的改變不會影響同名的全局變量a,這時候局部變量a與全局變量a其實是兩個完全沒有關係的變量。

其中的println函數也是Gox語言內置的,與其他語言的println基本相同。

* 另外注意,Gox語言也是大小寫敏感的,各種標識符(包括變量名、函數名、結構體名等)大小寫不同的話,都會被認為是不同的。


布爾類型

布爾類型英語中一般稱作boolean,也常簡稱bool,布爾類型數據的取值只有true和false兩個值,分別代表真與假、是或否等對立的概念。布爾類型的數值或變量經常被用於條件判斷分支代碼中。

<code>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)
/<code>

上面這段代碼中,printf函數也是Gox語言的內置函數,與其他語言的printf功能是基本一致,與Go語言中的printf函數完全一樣。因此,其中如果要輸出回車換行符也要用轉義字符“\\n”。

這段代碼執行後,輸出結果如下:

Gox語言中的基本數據類型及其轉換-GX2

其中,可以看出,變量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。


整數類型

<code>c1 = 19

c2 = 18

println(c1 + c2/3)

printfln("%T", 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)
/<code>

這段代碼的執行結果是:

Gox語言中的基本數據類型及其轉換-GX2

可以清晰地看出,在做了除法操作後,即使是整數相除,也會變成浮點數類型。並且整數都是64位的。另外,運算符++、--、*=,+=也都有效(還有-=,/=也都可以使用)。


浮點數類型

<code>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")
/<code>

執行結果為:

Gox語言中的基本數據類型及其轉換-GX2

需要注意的是,print也是Gox語言的內置函數,功能與其他語言中的print類似,如果要輸出回車換行符,可以用本代碼中所示的兩種方法,一種是加一個沒有參數的println函數,另一種是多輸出一個轉義符“\\n”。


字符串類型

下面是一些字符串賦值與操作的例子:

<code>s1 = "abc"

s2 = s1 * 3

pv("s2")

println(s1, "*", 3, "=", s2)

s3 = s2 / 3
printfln("s3: %v", s3)

s4 = "0.99"
s4 += 0.3

printfln("s4: %v", s4)

s5 = "上善若水"

pv("s5")

s6 = toByteSlice(s5)

println(s6)

s7 = toRuneSlice("上善若水")

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("toString(s7[1:3]) = %#v", toString(s7[1:3]))

pl("toString(toByteSlice(s7[1:3])) = %#v", toString(toByteSlice(s7[1:3])))

pl("toStringFromRuneSlice(s7[1:3]) = %#v", toStringFromRuneSlice(s7[1:3]))

pl("%c", s7[1])

for i = 0; i < len(s5); i++ {
pl("%v: %v", i, s5[i])
}

for v in s7 {
pl("%#T, %v", toChar(v), toChar(v))
}
/<code>

運行結果是:

Gox語言中的基本數據類型及其轉換-GX2

這裡需要注意的是:

  • pv函數可以查看變量的名稱、類型和值,在調試代碼的時候比較方便,但注意函數的參數要求傳入變量名稱,是個字符串;
  • pl函數與printfln作用相同,只是個簡寫;
  • 字符串做乘法的意義是會重複生成相同的字符串再合併起來;
  • 字符串加法的意義則是兩個字符串連接(或者叫合併)起來;
  • 與Go語言相同,對於UTF-8編碼的字符,轉成[]rune類型才可以處理正確,因此,要想正確地遍歷utf-8字符串,需要轉換成[]rune類型(rune類型本質上是int32類型),可以用toRuneSlice內置函數來進行;
  • 另外,注意把Rune切片轉換回字符串時,不能直接用toString函數,而必須要先轉換回ByteSlice(字節切片),用toByteSlice函數,這是一個坑;也可以用toStringFromRuneSlice函數,一步就可以了;
  • toChar函數可以把一個rune類型的數據轉換為對應字符的字符串表達形式;

空類型nil

Gox語言中的空類型實際上用到的場景沒有那麼多,主要用途有以下幾種情況:

  • 用於事先聲明一個變量,聲明的時候可能無法確定類型或取值;例如定義一個在後面賦值的全局變量時;
  • 用於調用Go語言庫中會返回nil類型的函數時進行交互和判斷,例如常見的error類型;

參看下面的例子:

<code>pv("a")

println(defined("a"))

a = 18

pv("a")

println(defined("a"))

b = nil

pv("b")

println(defined("b"))

tk = import("tk")

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())
}
/<code>

執行結果為:

Gox語言中的基本數據類型及其轉換-GX2

代碼中的tk.StrToInt函數就是會返回error類型值得函數,當傳入參數的字符串無法被轉換為整數類型時,返回的第二個值(error類型)將不是nil,而可以正常轉換時,將返回nil值。


數據類型的轉換

Gox語言中有不少“to”開頭的函數用於進行數據轉換,參看下面的例子:

<code>a = 1
b = 2

println("type of a is:", typeof(a))

println("a + b =", a+b)
printfln("a + b = %#v", a+b)

a1 = toString(a)
b1 = toString(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 = toFloat(a1)
b2 = toFloat(b1)

printfln("a2 + b2 = %#v", a2+b2)
printfln("type of a2 + b2 is: %T", a2+b2)
/<code>

運行結果如下:

<code>λ gox/>type of a 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
/<code>

這些“to”開頭的轉換函數包括:

toString/toStringSlice, toBool(and tryToBool which returns the result like (bool, error))/toBoolSlice, toFloat64/tryToFloat64/toFloat/toFloatSlice, toInt64/tryToInt64, toInt/tryToInt/toIntSlice, toRune/toRuneSlice, toByteSlice, toChar, toDuration

其中,toChar轉換出來的還是string類型,toDuration轉換出來的對應於Go語言的time.Duration類型。幾個“tryTo”開始的函數會嘗試進行轉換,如果不成功,會在第二個error類型的參數中返回錯誤信息。

另外,從這裡也可以看出Gox語言支持的一些本文沒提到的基礎類型,如rune、int64、float64等,但都大同小異,可以視情況選用。


分享到:


相關文章: