1. 程式人生 > >參照Java學Go(二)—— 變數和常量、基本資料型別

參照Java學Go(二)—— 變數和常量、基本資料型別

      前一篇從語言界定、環境搭建、helloword和包結構與java做了對比,接下來就開始從go的語法上和java進行對比。

說到語法,首先需要強調的一點就是“大小寫”,go和java一樣都是大小寫敏感的,另外有關大小寫的地方就是許可權相關:

Go在大小寫方面它有一些預設的行為:

  • 大寫字母開頭的變數是,是公有變數;小寫字母開頭的是私有變數。
  • 大寫字母開頭的函式也是一樣,相當於java中的帶public關鍵詞的公有函式;小寫字母開頭的相當於private關鍵詞的私有函式。

接下來說下繼續要對比學習的內容:變數、常量、還有基本資料型別。


一,變數

    go中變數的定義有多種方式,以string型別為例:
    
//定義一個string型別的變數
var vname string
//定義三個string型別的變數
var vname1, vname2, vname3 string
//定義並初始化
var vname string = “value”
//同時初始化多個變數
var vname1, vname2, vname3 string= “v1”, ”v2“, “v3”
//有點繁瑣?沒關係,可以直接忽略型別宣告(Go會根據其相應值的型別來幫你初始化它們),那麼上面的程式碼變成這樣了
var vname1, vname2, vname3 = “v1”, ”v2“, “v3”
//還繁瑣?好吧,繼續簡化,可以省略var,換成“:=”:
vname1, vname2, vname3 := “v1”, ”v2“, “v3”
    :=這個符號直接取代了var和type,這種形式叫做簡短宣告。不過它只能用在函式內部;函式外部使用會報錯,所以一般用var方式來定義全域性變數;

    變數定義在不同語言上都有自己的語法,對於java開發者來說可能感覺最不習慣的是把型別識別符號放到了變數名的後面(這個真的好彆扭),其他的還好,var的宣告,型別自動匹配等在js上也都比較習慣了。

    “_”變數,這個是go的一個特殊變數名,這個變數名錶示“被丟棄的”或者“無用的”,這個其實不用太在意,知道有這麼個變數就好了。需要提到的一點就是,和包類似,go的編譯器對於聲明瞭但是沒有使用的變數會報錯的,當然"_"除外,比如:
    
func main() {
    _, b := 1, 2
}
    這個時候編譯器就會報b的錯誤,對於_則不會,之前在將helloword的時候,把未使用的包取個“_”的別名就不會報錯是同一個原理。

二,常量
    go中宣告常量的關鍵字是const ,java中沒有,相當於final修飾符。
    
//go的宣告如下:
const Pi = 3.1415926
    常量這邊使用上和java沒啥差別,也沒有太多可說的,在go中有個特殊的常量:iota

    iota,可以認為是一個可以被編譯器修改的常量,通常用在列舉中。

    在每一個使用const關鍵定義時,iota的值被重置為0,在本次const定義中,每使用一次iota,其值就會自動增加1,如:

 const (
    a = iota
    b = iota
    c = iota
 )

    這樣a,b,c的值分別是0,1,2,還可以簡寫如下:

const (
    a = iota  //0
    b         //1
    c         //2
)

三,基本型別

    1,布林型
      布林型別當然是都有的了,和java的沒啥區別,沒啥好說的,簡單看一下:
      
//java:
boolean isOk=false;
//go:
var isOk bool   //or isOk:=false

    2,數值型
    2.1,整型
      java中的數值型別是有符號的,比如:
      
int a=-1,b=1;
      在go中,將屬性型別分開了,比如int分為了int(有符號)和uint(無符號),上邊的例子用go寫如下:
        
var a int=-1  //有符號
var b uint=1  //無符號
      說到數值型別,就一定要說範圍,我們知道,java中的int是有範圍的:-2147483648 ~ 2147483647
      
//java:
int a = -2147483648;
a = 2147483647;
a = 2147483648; //報錯,超出範圍了

//go:
var a int = -2147483648
a = 2147483647
a = 2147483648  //正確
      通過上面的測試,你會發現go的int沒有超出範圍報錯,是因為go的數值型別沒有範圍嗎?
      不是的,Go裡面也有直接定義好位數的型別:int8, int16, rune/int32, int64 和 byte/uint8, uint16, uint32, uint64 (rune是int32的別稱,byte是uint8的別稱)

      如下:

//go:
//int 32
var a1 int32 = 2147483647   //正確
//a1 = 2147483648         //錯誤,超出範圍

//uint32
var b1 uint32 = 2147483647*2+1  //最大範圍
//b1 = 2147483647*2+2     //報錯,超出範圍
      通過上面的測試,發現int32和java中的int範圍相同,而且有符號和無符號的長度相同。
      那go中的int是多少位呢?go的數值型別具體長度會根據系統平臺來決定,比我測試環境是64機器,那麼int的範圍與 int64相同(範圍就和java中的long範圍相同了,但不用像java中要以l結尾),如果是32位系統,則int的範圍與int32相同。

      說到與java型別的對應關係,java整型基本型別中還有short,在go中就相當於int16,當然go還有無符號的uint16;在java中還有byte,對應go中的int8,在go中,也有byte,和java的byte不同的是,go的byte是uint8,是無符號。

      注意:雖然在64位系統中int長度和int64相同,但是仍然是兩種型別,型別間不能相互轉化:
     
var a int         //32位系統
var a1 int32
var a3 rune = 10
a1=a3             //正確
a=a3              //錯誤
      不同型別不能轉化,rune和int32可以,因為rune和int32是相同型別,只是有兩個名稱而已。

    2.2,浮點型
      java中的浮點型有float和double,分別是32位和64位,在java中,float的數值必須以f或F結尾,與double區分,而double的數值可以加d也可以不加
      go中浮點型只有float32和float64(沒有float),預設是float64,分別對應java中的float和double


    2.3,複數
      複數,這個在java中不支援,在golang中是支援的,有兩中長度,分別是complex128(64位實數+64位虛數)和complex64(32位實數+32位虛數)
      
//go:
var a complex64 = 5+5i
fmt.Printf("Value is: %v", a)   //output: (5+5i)
//內建函式complex從指定的實部和虛部構建複數,內建函式real和imag用來獲取複數的實部和虛部:
var b complex128 = complex(-5, 5) // -5+5i
fmt.Println(real(b))           // "-5"
fmt.Println(imag(b))           // "5"
      對於複數,可能平時用到的機會比較少,用java雖然沒有支援該型別,但相關的複數操作可以自己實現。

      這裡可以列個表,對比一下go和java中的數值型別:

型別JavaGolang
整型byteint8
intint32/rune
longint64
int、int16、uint、uint8/byte、uint16, uint32, uint64
浮點型floatfloat32
doublefloat64
複數complex64、  complex128


    3,字串
      字串很常用,但是在java中字串(String)不是基本型別,java中針對字元的基本型別是char,一個單一的16位Unicode字元;
      在go中字串型別(string)是基本型別,固定長度不可以改變,採用UTF-8字符集編碼,用一對雙引號("")或反引號(``)括起來作為定義:
      
//字串初始化
var s = "hello"
//多行字元使用``
s1:= `"this 
      is 
      a
      test"
      `
      學java的人都知道,java中的Stirng是不可變類,在go中,string也是不可變的,但可以採用切片的方式來修改字串:
      
var s = "hello"
s = "ha" + s[2:]  // 字串雖不能更改,但可進行切片操作
fmt.Printf(s)     // 變成hallo

      切片是go中內建的一種特殊可變陣列,這個以後會說到。

      歡迎指教!