回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,20 +1,20 @@
## 3.1. 整型
Go言的數值類型包括幾種不同大小的整形、浮點數和複數。每種數值類型都定了對應的大小范和是否支持正負符號。讓我們先從整形數類型開始介
Go言的数值类型包括几种不同大小的整形、浮点数和复数。每种数值类型都定了对应的大小范和是否支持正负符号。让我们先从整形数类型开始介
Go言同提供了有符號和無符號類型的整數運算。里有int8、int16、int32和int64四截然不同大小的有符整形數類型,分别對應8、16、32、64bit大小的有符整形數,與此對應的是uint8、uint16、uint32和uint64四種無符號整形數類型。
Go言同提供了有符号和无符号类型的整数运算。里有int8、int16、int32和int64四截然不同大小的有符整形数类型,分别对应8、16、32、64bit大小的有符整形数,与此对应的是uint8、uint16、uint32和uint64四种无符号整形数类型。
這里還有兩種一般對應特定CPU平台器字大小的有符號和無符號整數int和uint其中int是用最泛的數值類型。這兩種類型都有同的大小32或64bit但是我不能此做任何的假;因不同的編譯器卽使在相同的硬件平台上可能生不同的大小。
这里还有两种一般对应特定CPU平台器字大小的有符号和无符号整数int和uint其中int是用最广泛的数值类型。这两种类型都有同的大小32或64bit但是我不能此做任何的假;因不同的编译器即使在相同的硬件平台上可能生不同的大小。
Unicode字符rune型是和int32等價的類型,通常用表示一Unicode碼點。這兩個名稱可以互使用。同byte也是uint8型的等價類byte型一般用於強調數值是一原始的數據而不是一小的整
Unicode字符rune型是和int32等价的类型,通常用表示一Unicode码点。这两个名称可以互使用。同byte也是uint8型的等价类byte型一般用于强调数值是一原始的数据而不是一小的整
後,還有一種無符號的整數類型uintptr有指定具的bit大小但是足以容納指針。uintptr類型隻有在底層編程是才需要特别是Go言和C言函數庫或操作繫統接口相交互的地方。我們將在第十三章的unsafe包相部分看到似的例子。
后,还有一种无符号的整数类型uintptr有指定具的bit大小但是足以容纳指针。uintptr类型只有在底层编程是才需要特别是Go言和C言函数库或操作系统接口相交互的地方。我们将在第十三章的unsafe包相部分看到似的例子。
不管它的具大小int、uint和uintptr是不同型的兄弟型。其中int和int32也是不同的型,使int的大小也是32bit在需要int作int32型的地方需要一個顯式的類型轉換操作,反之亦然。
不管它的具大小int、uint和uintptr是不同型的兄弟型。其中int和int32也是不同的型,使int的大小也是32bit在需要int作int32型的地方需要一个显式的类型转换操作,反之亦然。
其中有符號整數采用2的補碼形式表示也就是最高bit位用作表示符位,一n-bit的有符號數的值域是$$-2^{n-1}$$到$$2^{n-1}-1$$。無符號整數的所有bit位都用表示非負數值域是0到$$2^n-1$$。例如int8型整的值域是-128到127而uint8型整的值域是0到255。
其中有符号整数采用2的补码形式表示也就是最高bit位用作表示符位,一n-bit的有符号数的值域是$$-2^{n-1}$$到$$2^{n-1}-1$$。无符号整数的所有bit位都用表示非负数值域是0到$$2^n-1$$。例如int8型整的值域是-128到127而uint8型整的值域是0到255。
下面是Go言中關於算術運算、邏輯運算和比較運算的二元算符,它按照先級遞減的順序的排列:
下面是Go言中关于算术运算、逻辑运算和比较运算的二元算符,它按照先级递减的顺序的排列:
```
* / % << >> & &^
@@ -24,13 +24,13 @@ Unicode字符rune類型是和int32等價的類型通常用於表示一個Unic
||
```
二元算符有五種優先級。在同一個優先級,使用左優先結合規則,但是使用括可以明確優先順序,使用括也可以用於提陞優先級,例如`mask & (1 << 28)`
二元算符有五种优先级。在同一个优先级,使用左优先结合规则,但是使用括可以明确优先顺序,使用括也可以用于提升优先级,例如`mask & (1 << 28)`
對於上表中前行的算符,例如+算符有一個與賦值相合的對應運算符+=,可以用於簡化賦值語句。
对于上表中前行的算符,例如+算符有一个与赋值相合的对应运算符+=,可以用于简化赋值语句。
術運算符+、-、`*``/`可以適用與於整數、浮點數和複數,但是取模算符%僅用於整數間的運算。對於不同編程語言,%取模算的行可能不相同。在Go言中,%取模算符的符和被取模的符號總是一致的,因此`-5%3``-5%-3`果都是-2。除法算符`/`的行爲則依賴於操作是否爲全爲整數,比如`5.0/4.0`果是1.25但是5/4的果是1爲整數除法向着0方向截斷餘數
术运算符+、-、`*``/`可以适用与于整数、浮点数和复数,但是取模算符%仅用于整数间的运算。对于不同编程语言,%取模算的行可能不相同。在Go言中,%取模算符的符和被取模的符号总是一致的,因此`-5%3``-5%-3`果都是-2。除法算符`/`的行为则依赖于操作是否为全为整数,比如`5.0/4.0`果是1.25但是5/4的果是1为整数除法向着0方向截断余数
如果一個算術運算的果,不管是有符或者是無符號如果需要更多的bit位才能正表示的,就説明計算結果是溢出了。超出的高位的bit位部分將被丟棄。如果原始的值是有符號類型,而且最左的bit是1的,那麽最終結果可能是例如int8的例子
如果一个算术运算的果,不管是有符或者是无符号如果需要更多的bit位才能正表示的,就说明计算结果是溢出了。超出的高位的bit位部分将被丢弃。如果原始的值是有符号类型,而且最左的bit是1的,那么最终结果可能是例如int8的例子
```Go
var u uint8 = 255
@@ -40,7 +40,7 @@ var i int8 = 127
fmt.Println(i, i+1, i*i) // "127 -128 1"
```
兩個相同的整數類型可以使用下面的二元比較運算符行比;比較表達式的果是布爾類型。
两个相同的整数类型可以使用下面的二元比较运算符行比;比较表达式的果是布尔类型。
```
== equal to
@@ -51,31 +51,31 @@ fmt.Println(i, i+1, i*i) // "127 -128 1"
>= greater than or equal to
```
上,布型、數字類型和字符串等基本型都是可比的,也就是説兩個相同型的值可以用==和!=行比。此外,整、浮點數和字符串可以根據比較結果排序。多其它型的值可能是不可比的,因此也就可能是不可排序的。對於我們遇到的每種類型,我需要保證規則的一致性。
上,布型、数字类型和字符串等基本型都是可比的,也就是说两个相同型的值可以用==和!=行比。此外,整、浮点数和字符串可以根据比较结果排序。多其它型的值可能是不可比的,因此也就可能是不可排序的。对于我们遇到的每种类型,我需要保证规则的一致性。
里是一元的加法和減法運算符:
里是一元的加法和减法运算符:
```
+ 一元加法 (效果)
- 負數
+ 一元加法 (效果)
- 负数
```
對於整數+x是0+x的簡寫-x是0-x的簡寫;對於浮點數和複數+x就是x-x是x 的負數
对于整数+x是0+x的简写-x是0-x的简写;对于浮点数和复数+x就是x-x是x 的负数
Go語言還提供了以下的bit位操作算符前面4操作算符併不區分是有符號還是無符號數
Go语言还提供了以下的bit位操作算符前面4操作算符并不区分是有符号还是无符号数
```
& 位算 AND
| 位算 OR
^ 位算 XOR
& 位算 AND
| 位算 OR
^ 位算 XOR
&^ 位清空 (AND NOT)
<< 左移
>> 右移
```
位操作算符`^`二元算符是按位XOR用作一元算符表示按位取反;也就是,它返迴一個每個bit位都取反的。位操作算符`&^`按位置零AND NOT`z = x &^ y`果z的bit位0如果對應y中bit位1的,否則對應的bit位等x相的bit位的值。
位操作算符`^`二元算符是按位XOR用作一元算符表示按位取反;也就是,它返回一个每个bit位都取反的。位操作算符`&^`按位置零AND NOT`z = x &^ y`果z的bit位0如果对应y中bit位1的,否则对应的bit位等x相的bit位的值。
下面的代演示了如何使用位操作解uint8型值的8個獨立的bit位。它使用了Printf函的%b參數打印二進製格式的字;其中%08b中08表示打印至少8字符度,不足的前部分用0填充。
下面的代演示了如何使用位操作解uint8型值的8个独立的bit位。它使用了Printf函的%b参数打印二进制格式的字;其中%08b中08表示打印至少8字符度,不足的前部分用0填充。
```Go
var x uint8 = 1<<1 | 1<<5
@@ -99,13 +99,13 @@ fmt.Printf("%08b\n", x<<1) // "01000100", the set {2, 6}
fmt.Printf("%08b\n", x>>1) // "00010001", the set {0, 4}
```
6.5節給出了一可以遠大於一個字節的整集的實現。)
6.5节给出了一可以远大于一个字节的整集的实现。)
`x<<n``x>>n`移位算中,定了移位操作bit部分必須是無符號數被操作的x可以是有符號或無符號數。算上,一`x<<n`左移算等價於乘以$$2^n$$,一`x>>n`右移算等價於除以$$2^n$$。
`x<<n``x>>n`移位算中,定了移位操作bit部分必须是无符号数被操作的x可以是有符号或无符号数。算上,一`x<<n`左移算等价于乘以$$2^n$$,一`x>>n`右移算等价于除以$$2^n$$。
左移算用零填充右空缺的bit位無符號數的右移算也是用0填充左空缺的bit位但是有符號數的右移運算會用符位的值填充左空缺的bit位。因爲這個原因,最好用無符號運算,這樣你可以將整數完全作一bit位模式理。
左移算用零填充右空缺的bit位无符号数的右移算也是用0填充左空缺的bit位但是有符号数的右移运算会用符位的值填充左空缺的bit位。因为这个原因,最好用无符号运算,这样你可以将整数完全作一bit位模式理。
管Go言提供了無符號數和運算,卽使數值本身不可能出現負數我們還是傾向於使用有符的int型,就像數組的長度那樣,雖然使用uint無符號類型似乎是一更合理的選擇。事上,置的len函數返迴一個有符的int可以像下面例子那樣處理逆序循
管Go言提供了无符号数和运算,即使数值本身不可能出现负数我们还是倾向于使用有符的int型,就像数组的长度那样,虽然使用uint无符号类型似乎是一更合理的选择。事上,置的len函数返回一个有符的int可以像下面例子那样处理逆序循
```Go
medals := []string{"gold", "silver", "bronze"}
@@ -114,13 +114,13 @@ for i := len(medals) - 1; i >= 0; i-- {
}
```
另一個選擇對於上面的例子來説將是災難性的。如果len函數返迴一個無符號數,那i也將是無符號的uint型,然後條`i >= 0`則永遠爲眞。在三次迭代之,也就是`i == 0`i--語句將不會産生-1而是成一uint型的最大值(可能是$$2^64-1$$),然medals[i]表達式將發生運行時panic§5.9),也就是試圖訪問一個slice范以外的元素。
另一个选择对于上面的例子来说将是灾难性的。如果len函数返回一个无符号数,那i也将是无符号的uint型,然后条`i >= 0`则永远为真。在三次迭代之,也就是`i == 0`i--语句将不会产生-1而是成一uint型的最大值(可能是$$2^64-1$$),然medals[i]表达式将发生运行时panic§5.9),也就是试图访问一个slice范以外的元素。
於這個原因,無符號數往往有在位算或其它特殊的運算場景才使用就像bit集合、分析二進製文件格式或者是哈希和加密操作等。它通常不用於僅僅是表達非負數量的合。
于这个原因,无符号数往往有在位算或其它特殊的运算场景才使用就像bit集合、分析二进制文件格式或者是哈希和加密操作等。它通常不用于仅仅是表达非负数量的合。
一般來説,需要一個顯式的轉換將一個值從一種類型轉化位另一種類型,且算術和邏輯運算的二元操作中必是相同的型。雖然這偶爾會導致需要很的表式,但是它消除了所有和型相關的問題,而且也使得程序容易理解。
一般来说,需要一个显式的转换将一个值从一种类型转化位另一种类型,且算术和逻辑运算的二元操作中必是相同的型。虽然这偶尔会导致需要很的表式,但是它消除了所有和型相关的问题,而且也使得程序容易理解。
在很多景,遇到似下面的代通用的錯誤
在很多景,遇到似下面的代通用的错误
```Go
var apples int32 = 1
@@ -128,19 +128,19 @@ var oranges int16 = 2
var compote int = apples + oranges // compile error
```
當嚐試編譯這三個語句時,將産生一個錯誤信息:
当尝试编译这三个语句时,将产生一个错误信息:
```
invalid operation: apples + oranges (mismatched types int32 and int16)
```
這種類型不匹配的問題可以有幾種不同的方法脩複,最常方法是將它們都顯式轉型爲一個常見類型:
这种类型不匹配的问题可以有几种不同的方法修复,最常方法是将它们都显式转型为一个常见类型:
```Go
var compote = int(apples) + int(oranges)
```
如2.5所述,對於每種類型T如果轉換允許的話類型轉換操作T(x)將x轉換爲T類型。多整形數之間的相互轉換併不會改變數值;它們隻是告訴編譯器如何解釋這個值。但是對於將一個大尺寸的整數類型轉爲一個小尺寸的整數類型,或者是將一個浮點數轉爲整數,可能會改變數值或失精度:
如2.5所述,对于每种类型T如果转换允许的话类型转换操作T(x)将x转换为T类型。多整形数之间的相互转换并不会改变数值;它们只是告诉编译器如何解释这个值。但是对于将一个大尺寸的整数类型转为一个小尺寸的整数类型,或者是将一个浮点数转为整数,可能会改变数值或失精度:
```Go
f := 3.141 // a float64
@@ -150,16 +150,16 @@ f = 1.99
fmt.Println(int(f)) // "1"
```
點數到整數的轉換將丟失任何小部分,然後向數軸零方向截。你應該避免可能超出目標類型表示范圍的數值類型轉換,因爲截斷的行可能依賴於具體的實現
点数到整数的转换将丢失任何小部分,然后向数轴零方向截。你应该避免可能超出目标类型表示范围的数值类型转换,因为截断的行可能依赖于具体的实现
```Go
f := 1e100 // a float64
i := int(f) // 果依賴於具體實現
i := int(f) // 果依赖于具体实现
```
任何大小的整字面值都可以用以0始的八進製格式書寫例如0666或用以0x或0X開頭的十六進製格式書寫例如0xdeadbeef。十六進製數字可以用大或小字母。如今八進製數據通常用POSIX操作繫統上的文件訪問權限標誌,十六進製數字則更強調數字值的bit位模式。
任何大小的整字面值都可以用以0始的八进制格式书写例如0666或用以0x或0X开头的十六进制格式书写例如0xdeadbeef。十六进制数字可以用大或小字母。如今八进制数据通常用POSIX操作系统上的文件访问权限标志,十六进制数字则更强调数字值的bit位模式。
使用fmt包打印一個數值時,我可以用%d、%o或%x參數控製輸出的進製格式,就像下面的例子:
使用fmt包打印一个数值时,我可以用%d、%o或%x参数控制输出的进制格式,就像下面的例子:
```Go
o := 0666
@@ -170,11 +170,11 @@ fmt.Printf("%d %[1]x %#[1]x %#[1]X\n", x)
// 3735928559 deadbeef 0xdeadbeef 0XDEADBEEF
```
請註意fmt的兩個使用技巧。通常Printf格式化字符串包含多個%參數時將會包含對應相同量的外操作,但是%之`[1]`詞告訴Printf函再次使用第一操作。第二,%`#`詞告訴Printf在用%o、%x或%X輸出時生成0、0x或0X前
请注意fmt的两个使用技巧。通常Printf格式化字符串包含多个%参数时将会包含对应相同量的外操作,但是%之`[1]`词告诉Printf函再次使用第一操作。第二,%`#`词告诉Printf在用%o、%x或%X输出时生成0、0x或0X前
字符面值通過一對單引號直接包含對應字符。最簡單的例子是ASCII中似'a'法的字符面值,但是我也可以通過轉義的數值來表示任意的Unicode碼點對應的字符,馬上將會看到這樣的例子。
字符面值通过一对单引号直接包含对应字符。最简单的例子是ASCII中似'a'法的字符面值,但是我也可以通过转义的数值来表示任意的Unicode码点对应的字符,马上将会看到这样的例子。
字符使用`%c`參數打印,或者是用`%q`參數打印帶單引號的字符:
字符使用`%c`参数打印,或者是用`%q`参数打印带单引号的字符:
```Go
ascii := 'a'