1. 程式人生 > >Go語言-基本型別(int,float,bool,byte,string)

Go語言-基本型別(int,float,bool,byte,string)

1 函式格式

定義格式:

func functionName(para1 para1Type, para2 para2Type) (ret1 ret1Type, ret2 ret2Type) {
    ...
}

函式名用駱駝命名法。
main函式無引數無返回。
其他函式可以有多個返回值,跟Python一樣。

每個包在被引入或者main包開始執行的時候,可以有一個首先執行的函式,類似於建構函式:

func init () {
    ...
}

2 型別

Go語言的靜態性,體現在型別上,需要顯示定義,顯示轉換。
變數、常量,具有型別。
宣告形式:

var varName varType
var varName varType = xxx
varName := xxx

var s string
var v int = 5
a := 5.0

型別轉換:

valueOfTypeB = typeB(valueOfTypeA)

a := 5.0
b := int(a)

2.1 基本型別

基本型別
int
float
bool
byte

2.1.1 int

int 範圍
int8 (-128 -> 127)
int16 (-32768 -> 32767)
int32 (-2,147,483,648 -> 2,147,483,647)
int64 (-9,223,372,036,854,775,808 -> 9,223,372,036,854,775,807)
uint8 (0 -> 255)
uint16 (0 -> 65,535)
uint32 (0 -> 4,294,967,295)
uint64 (0 -> 18,446,744,073,709,551,615

從上面看不到int/uint型別,Go語言的int/uint型別,是不可移植的型別,其長度根據宿主機的機器字長決定,比如32位的架構,int/uint就是int32/uint32;64位架構,int/uint就是int64/uint64。

uintptr是宿主系統內足夠存放一個指標的型別。

八進位制:0777
十六進位制:0xFF
格式化輸出:%d %x %X

2.1.2 float

float 精度
float32(+- 1e-45 -> +- 3.4 * 1e38) 精確位數小數點後7位
float64(+- 5 * 1e-324 -> 107 * 1e308) 精確位數小數點後15位

格式化輸出:%g %f %e

2.1.3 bool

true或者false。
比較運算表示式(==, !=),可以返回bool型別的結果。
bool型別可以參與到邏輯運算中(!, &&, ||),採用短路運算。
格式化輸出用 %t 表示bool型別。

2.1.4 byte

byte其實是整型的特殊用例。byte是uint8的別名。

var ch byte = 'A'
var ch byte = 65
var ch byte = '\0x41' //0x後面必須跟2位的16進位制數

如果是UTF-8,就不能用byte了,要用int:

var ch int = '\u0041'
var ch2 int = '\u03B2'
fmt.Printf("%d, %d", ch, ch2) //int
fmt.Printf("%c, %c", ch, ch2) //字元
fmt.Printf("%X, %X", ch, ch2) //UTF-8位元組
fmt.Printf("%U, %U", ch, ch2) //UTF-8 code point

65, 946
A, β
41, 3B2
U+0041, U+03B2

字元型別的一些判定函式,在系統包unicode裡邊:

unicode.IsLetter(ch)
unicode.IsDigit(ch)
unicode.IsSpace(ch)

2.2 字串

其實是個位元組型別的定常陣列,但是一旦初始化後,內容不可變。
轉義字元還是老樣子:

轉義字元
\n
\r
\t
\u \U Unicode字元
\\

新的東西是非解釋字串,裡邊的內容不解釋,沒有轉義,用反括號(鍵盤1左邊的那個鍵)括起來:

`This is a raw string \n`
This is a raw string \n

字串的對比,可以通過:

字串對比運算子
==
!=
<
<=
>
>=

比較的方式是按照位元組來對比。

2.2.1 長度

len(str)

2.2.2 字元

str[0]
str[1]
str[len(str) - 1]

2.2.3 拼接

s = s1 + s2
strings.Join()
bytes.Buffer

2.2.4 strings 包

前後綴

strings.HasPrefix(s, prefix string) bool //s是否以prefix開頭
strings.HasSuffix(s, suffix string) bool //s是否以suffix結尾

包含

strings.Contains(s, substr string) bool //s是否包含substr

index位置

strings.Index(s, str string) int //str在s中的位置,-1表示不包含
strings.LastIndex(s, str string) int //s中最後一個str的位置,-1表示不包含
strings.IndexRune(s string, r rune) int //非ASCII字元的定位

替換

strings.Replace(str, old, new, n) string 
//str中前n個old換成new,n=-1表示全部替換
//並不會改變str,返回一個新的string

統計個數

strings.Count(s, str string) int //str在s中出現的個數

重複字串

strings.Repeat(s, count int) string //s重複count次,生成一個新的string

大小寫

strings.ToLower(s) string //s裡邊全部Unicode字元變成小寫
strings.ToUpper(s) string //s裡邊全部Unicode字元變成大寫

字串修剪

strings.TrimSpace(s) string //刪除頭尾兩端的空白字元
strings.Trim(s, cutset) string //刪除頭尾兩端的cutset字串
strings.TrimLeft(s, cutset) string
strings.TrimRight(s, cutset) string

字串分割

strings.Fields(s) []string //按照空白字元分割s,返回一個slice
strings.Split(s, sep) []string //按照指定字元分割s,返回slice

拼接slice

strings.Join(sl []string, sep string) string //用分割符把slice拼接到一起

從字串中讀取內容

strings.NewReader(str) *Reader //例項化一個Reader,可以用Reader的若干方法
.Len()
.Read(b []byte) (n int, err error) //把str的內容讀入到一個[]byte中

關於Reader的Read,有個例子,反覆Read到一個[]byte中:

    func main() {  
        s := "Hello World!"  
        // 建立 Reader  
        r := strings.NewReader(s)  
        // 建立長度為 5 個位元組的緩衝區  
        b := make([]byte, 5)  
        // 迴圈讀取 r 中的字串  
        for n, _ := r.Read(b); n > 0; n, _ = r.Read(b) {  
            fmt.Printf("%q, ", b[:n]) // "Hello", " Worl", "d!"  
        }  
    }  

2.2.5 strconv 包

字串和其他型別的轉換

strconv.IntSize //當前平臺int的字長
strconv.Itoa(i int) string //整數轉字串
strconv.FormatFloat(f float64, fmt byte, prec int, bitSize int) string //float64 轉字串, fmt可以是'b', 'e', 'f', 'g';prec表示精度;bitSize 32表示float32,64表示float64
strconv.Atoi(s string) (i int, err error) //字串轉整數
strconv.ParseFloat(s string, bitSize int) (f float64, err error) //字串轉float64

2.3 常量

const identifier [type] = value

const b string = "abc"
const b = "abc"
const Pi = 3.14159

注意上面的常量定義,型別是可以省略的,但是不等於沒有型別了,省略關鍵字的時候,型別是編譯器自己判斷出來並加上的。

常量的值必須在編譯時可知,執行時才知道的值不能作為常量定義的右值。

const c1 = 2/3 // OK
const c2 = getNumber() // 引發構建錯誤: getNumber() used as value

2.4 列舉

列舉用的是常量,沒有專門的列舉型別,奉行能少就少,能用別的代替就用別的代替的原則:

const (
    Unknown = 0
    Female = 1
    Male = 2
)
const (
    a = iota
    b
    c
) 
// 每一個新行,iota都加1,所以a, b, c = 0, 1, 2
// 每遇到const,iota就歸零

2.5 變數

名字在前,型別在後。

var a, b *int //a和b都是*int型別
var (
    a int
    b bool
    str string
)

變數聲明後就有零值了,所以都是經過初始化的:

  • int 0
  • float 0.0
  • bool false
  • string “”
  • * nil

作用域
1. 函式外,全域性,包內甚至包外(首字母大寫)可用
2. 函式內,程式碼塊外,函式可用
3. 函式內,程式碼塊內(if, for等含有{}的部分),程式碼塊內可用