make zh2tw

This commit is contained in:
chai2010
2015-12-21 12:52:25 +08:00
parent 14665b4d9c
commit d024df28e9
7 changed files with 131 additions and 131 deletions

View File

@@ -1,20 +1,20 @@
## 3.1. 整型
Go言的数值类型包括几种不同大小的整形, 浮点数, 和复数. 每种数值类型都定了对应的大小范和是否有正负符号. 让我们先从整形数类型开始介.
Go言的數值類型包括幾種不同大小的整形, 浮點數, 和複數. 每種數值類型都定了對應的大小范和是否有正負符號. 讓我們先從整形數類型開始介.
Go同提供了有符号和无符号的整数运算. 里有四int8, int16, int32 和 int64截然不同大小的有符整形数类型, 分别对应 8, 16, 32, 64 bit 大小的有符整形, 与此对应的是 uint8, uint16, uint32, 和 uint64 四种无符号整形数类型.
Go同提供了有符號和無符號的整數運算. 里有四int8, int16, int32 和 int64截然不同大小的有符整形數類型, 分别對應 8, 16, 32, 64 bit 大小的有符整形, 與此對應的是 uint8, uint16, uint32, 和 uint64 四種無符號整形數類型.
这里还有两种对应特定平最天然或最有效率的大小有符号和无符号整数int和uint; 其中int是用最广泛的数值类型. 这两种类型都有同的大小, 32 或 64 bit, 但是我不能此做任何的假; 因不同的编译器在相同的硬件平上可能生不同的大小.
這里還有兩種對應特定平最天然或最有效率的大小有符號和無符號整數int和uint; 其中int是用最泛的數值類型. 這兩種類型都有同的大小, 32 或 64 bit, 但是我不能此做任何的假; 因不同的編譯器在相同的硬件平上可能生不同的大小.
字符rune型是和int32等价的类型, 通常用表示一Unicode码点. 这两个名称可以互使用. 同byte也是uint8型的等价类型, byte型用于强调数值是一原始的数据而不是一小的整.
字符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的补码形式表示, 也就是最高位用作符位, 一nbit的有符号数的值域是 `-2^(n-1)``(2^(n-1)) - 1`. 无符号整数的所有bit位都用表示非负数, 值域是 0 到 `(2^n) - 1`. 例如, int8 的值域是 -128 到 127, 而 uint8 的值域是 0 到 255.
有符號數采用2的補碼形式表示, 也就是最高位用作符位, 一nbit的有符號數的值域是 `-2^(n-1)``(2^(n-1)) - 1`. 無符號整數的所有bit位都用表示非負數, 值域是 0 到 `(2^n) - 1`. 例如, int8 的值域是 -128 到 127, 而 uint8 的值域是 0 到 255.
下面是Go中关于算术, 逻辑和比的二元算符按照先级递减的顺序的列表:
下面是Go中關於算術, 邏輯和比的二元算符按照先級遞減的順序的列表:
```
* / % << >> & &^
@@ -24,14 +24,14 @@ Go同时提供了有符号和无符号的整数运算. 这里有四种int8, int1
||
```
二元算符有五种优先级. 在同一优先级, 使用左优先结合律, 使用括可以明确优先顺序, 括也可以用于提升优先级, 例如 `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
@@ -41,7 +41,7 @@ var i int8 = 127
fmt.Println(i, i+1, i*i) // "127 -128 1"
```
两个相同的整数类型可以使用下面的二元比较运算符行比; 比较表达式的果是布尔类型.
兩個相同的整數類型可以使用下面的二元比較運算符行比; 比較表達式的果是布爾類型.
```
== equal to
@@ -52,33 +52,33 @@ 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位1, 如果对应y中bit位1, 否则对应的bit位等x相的bit位的值.
位操作算符 `^`二元算符是按位或(XOR), 用作一元算符表示按位取反; 也就是, 它返迴一個每個bit位都取反的. 位操作算符 `&^`按位置零(AND NOT): 表`z = x &^ y` 果z的bit位1, 如果對應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
@@ -102,13 +102,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"}
@@ -117,13 +117,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), 也就是试图访问一个切片范以外的元素.
另一個選擇將是災難性的. 如果 len 返迴一個無符號數, 那 i 也將是無符號的 uint, 然後條件 i >= 0 則永遠爲眞. 在三次迭代之, 也就是 i == 0 , i-- 語句將不會産生 -1, 而是成一uint的最大值(可能是 2^64 - 1), 然 medals[i] 表達式將發生運行時 panic 常(§5.9), 也就是試圖訪問一個切片范以外的元素.
出于这个原因, 无符号数往往有在位算或其它特殊的算常见才会使用, 就像 bit 集合, 分形二进制文件格式, 或者是哈希和加密操作等. 它通常不用于仅仅是表达非负数量的合.
齣於這個原因, 無符號數往往有在位算或其它特殊的算常見纔會使用, 就像 bit 集合, 分形二進製文件格式, 或者是哈希和加密操作等. 它通常不用於僅僅是表達非負數量的合.
一般来说, 需要一个显式的转换将一个值从一种类型转化位另一种类型, 且算术和逻辑运算的二元操作中必是相同的型. 虽然这偶尔会导致很的表式, 但是它消除了所有的型相关的问题, 也使得程序容易理解.
一般來説, 需要一個顯式的轉換將一個值從一種類型轉化位另一種類型, 且算術和邏輯運算的二元操作中必是相同的型. 雖然這偶爾會導致很的表式, 但是它消除了所有的型相關的問題, 也使得程序容易理解.
其他类似场景下, 考下面这个代码:
其他類似場景下, 考下面這個代碼:
```Go
var apples int32 = 1
@@ -131,19 +131,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
@@ -153,16 +153,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
@@ -173,18 +173,18 @@ 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'
unicode := ''
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]c %[1]q\n", unicode) // "22269 ''"
fmt.Printf("%d %[1]q\n", newline) // "10 '\n'"
```