基础数据类型
二元運算符
下面是Go語言中關於算術運算、邏輯運算和比較運算的二元運算符,它們按照先級遞減的順序的排列:
* / % << >> & &^ + - | ^ == != < <= > >= && ||
bit位操作運算符
Go語言還提供了以下的bit位操作運算符,前面4個操作運算符併不區分是有符號還是無符號數:
& 位運算 AND | 位運算 OR ^ 位運算 XOR &^ 位清空 (AND NOT) << 左移 >> 右移
fmt 打印技巧
當使用fmt包打印一個數值時,我們可以用%d、%o或%x參數控製輸出的進製格式,就像下面的例子:
o := 0666
fmt.Printf("%d %[1]o %#[1]o\n", o) // "438 666 0666"
x := int64(0xdeadbeef)
fmt.Printf("%d %[1]x %#[1]x %#[1]X\n", x)
// Output:
// 3735928559 deadbeef 0xdeadbeef 0XDEADBEEF
%之後的[1]副詞告訴Printf函數再次使用第一個操作數%後的#副詞告訴Printf在用%o、%x或%X輸出時生成0、0x或0X前綴
单引号的使用
字符面值通過一對單引號直接包含對應字符。最簡單的例子是ASCII中類似'a'寫法的字符面值,但是我們也可以通過轉義的數值來表示任意的Unicode碼點對應的字符,馬上將會看到這樣的例子。
字符使用%c參數打印,或者是用%q參數打印帶單引號的字符:
ascii := 'a' unicode := '国' newline := '\n' fmt.Printf("%d %[1]c %[1]q\n", ascii) // "97 a 'a'" fmt.Printf("%d %[1]c %[1]q\n", unicode) // "22269 国 '国'" fmt.Printf("%d %[1]q\n", newline) // "10 '\n'"
浮点数精度
一個float32類型的浮點數可以提供大約6個十進製數的精度,而float64則可以提供約15個十進製數的精度;通常應該優先使用float64類型,因爲float32類型的纍計計算誤差很容易擴散,併且float32能精確表示的正整數併不是很大(譯註:因爲float32的有效bit位隻有23個,其它的bit位用於指數和符號;當整數大於23bit能表達的范圍時,float32的表示將出現誤差):
var f float32 = 16777216 // 1 << 24 fmt.Println(f == f+1) // "true"!
math包中除了提供大量常用的數學函數外,還提供了IEEE754浮點數標準中定義的特殊值的創建和測試:正無窮大和負無窮大,分别用於表示太大溢出的數字和除零的結果;還有NaN非數,一般用於表示無效的除法操作結果0/0或Sqrt(-1).
var z float64 fmt.Println(z, -z, 1/z, -1/z, z/z) // "0 -0 +Inf -Inf NaN"
复数
Go語言提供了兩種精度的複數類型:complex64和complex128,分别對應float32和float64兩種浮點數精度。內置的complex函數用於構建複數,內建的real和imag函數分别返迴複數的實部和虛部:
var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(imag(x*y)) // "10"
字符串基本用法
s := "hello, world" fmt.Println(len(s)) // "12" fmt.Println(s[0], s[7]) // "104 119" ('h' and 'w') c := s[len(s)] // panic: index out of range s[0] = 'L' // compile error: cannot assign to s[0]
常见包
一些使用实例
gopl.io/ch3/basename2 func basename(s string) string { slash := strings.LastIndex(s, "/") // -1 if "/" not found s = s[slash+1:] if dot := strings.LastIndex(s, "."); dot >= 0 { s = s[:dot] } return s }
// intsToString is like fmt.Sprint(values) but adds commas. func intsToString(values []int) string { var buf bytes.Buffer buf.WriteByte('[') for i, v := range values { if i > 0 { buf.WriteString(", ") } fmt.Fprintf(&buf, "%d", v) } buf.WriteByte(']') return buf.String() } func main() { fmt.Println(intsToString([]int{1, 2, 3})) // "[1, 2, 3]" }
x := 123 y := fmt.Sprintf("%d", x) fmt.Println(y, strconv.Itoa(x)) // "123 123" fmt.Println(strconv.FormatInt(int64(x), 2)) // "1111011" s := fmt.Sprintf("x=%b", x) // "x=1111011" x, err := strconv.Atoi("123") // x is an int y, err := strconv.ParseInt("123", 10, 64) // base 10, up to 64 bits
字符串的“不可修改”
s[0] = "a"字符串拼接的耗时所在字符串的不可修改
type stringStruct struct { str unsafe.Pointer len int }
常量
所有常量的运算都可以在编译器完成,这样可以减少运行时的工作,也方便其他编译优化。当操作数是常量时,一些运行时的错误也可以在编译时被发现,例如整数除零、字符串索引越界、任何导致无效浮点数的操作等。
基础用法
- 因为它们的值是在编译器就确定的,因此常量可以是构成类型的一部分,例如用于指定数组类型的长度:
const IPv4Len = 4 // parseIPv4 parses an IPv4 address (d.d.d.d). func parseIPv4(s string) IP { var p [IPv4Len]byte // ... }
- 常量可以批量声明
const ( a = 1 b c = 2 d )
iota 常量生成器
type Weekday int const ( Sunday Weekday = iota Monday Tuesday Wednesday Thursday Friday Saturday )
无类型常量
Go語言的常量有個不同尋常之處。雖然一個常量可以有任意有一個確定的基礎類型,例如int或float64,或者是類似time.Duration這樣命名的基礎類型,但是許多常量併沒有一個明確的基礎類型。編譯器爲這些沒有明確的基礎類型的數字常量提供比基礎類型更高精度的算術運算;你可以認爲至少有256bit的運算精度。這里有六種未明確類型的常量類型,分别是無類型的布爾型、無類型的整數、無類型的字符、無類型的浮點數、無類型的複數、無類型的字符串。
通過延遲明確常量的具體類型,無類型的常量不僅可以提供更高的運算精度,而且可以直接用於更多的表達式而不需要顯式的類型轉換
引用
欢迎大家关注我的公众号