This commit is contained in:
chai2010
2015-12-17 13:13:42 +08:00
parent b28bebc617
commit 1d9c08c03b
6 changed files with 54 additions and 54 deletions

View File

@@ -1,17 +1,17 @@
## 3.4. 佈爾型 ## 3.4. 佈爾型
个布尔类型的值只有两种 true 和 false. if 和 for 句的件部分都是布尔类型的值, 且 == 和 < 等比操作也会产生布尔型的值. 一元操作符 `!` 对应逻辑非操作, 因此 `!true` 的值 `false`, 也可以 `(!true==false)==true`, 虽然表达方式不一, 过我们一般会采用简洁的布尔表达, 就像用 x 来表 `x==true`. 箇佈爾類型的值隻有兩種 true 和 false. if 和 for 句的件部分都是佈爾類型的值, 且 == 和 < 等比操作也會產生佈爾型的值. 一元操作符 `!` 對應邏輯非操作, 因此 `!true` 的值 `false`, 也可以 `(!true==false)==true`, 雖然錶達方式不一, 過我們一般會採用簡潔的佈爾錶達, 就像用 x 來錶 `x==true`.
布尔值可以和 && (AND) || (OR) 操作符结合, 且可能有短路行: 如果算符左值已可以定整个布尔表达式的值, 么运算符右的值不在被, 因此下面的表达式总是安全的: 佈爾值可以和 && (AND) || (OR) 操作符結閤, 且可能有短路行: 如果算符左值已可以定整箇佈爾錶達式的值, 麽運算符右的值不在被, 因此下麪的錶達式總是安全的:
```Go ```Go
s != "" && s[0] == 'x' s != "" && s[0] == 'x'
``` ```
其中 s[0] 应用于空字符串会导致 panic . 其中 s[0] 應用於空字符串會導緻 panic .
`&&` 优先级 `||` (: `&&` 对应逻辑乘法, `||` 对应逻辑加法, 乘法比加法优先级要高), 形式的布尔表达式是不需要加小括弧的: `&&` 優先級 `||` (: `&&` 對應邏輯乘法, `||` 對應邏輯加法, 乘法比加法優先級要高), 形式的佈爾錶達式是不需要加小括弧的:
```Go ```Go
if 'a' <= c && c <= 'z' || if 'a' <= c && c <= 'z' ||
@@ -21,7 +21,7 @@ if 'a' <= c && c <= 'z' ||
} }
``` ```
布尔值并不会隐式转换为数字值0或1, 反之亦然. 使用一个显式的if语句辅助转换: 佈爾值並不會隱式轉換為數字值0或1, 反之亦然. 使用一箇顯式的if語句輔助轉換:
```Go ```Go
i := 0 i := 0
@@ -30,7 +30,7 @@ if b {
} }
``` ```
如果需要常做似的转换, 成一个函数会更方便: 如果需要常做似的轉換, 成一箇函數會更方便:
```Go ```Go
// btoi returns 1 if b is true and 0 if false. // btoi returns 1 if b is true and 0 if false.
@@ -42,7 +42,7 @@ func btoi(b bool) int {
} }
``` ```
字到布尔型的逆转换则非常简单, 过为了保持对称, 也可以包装一个函数: 字到佈爾型的逆轉換則非常簡單, 過為了保持對稱, 也可以包裝一箇函數:
```Go ```Go
// itob reports whether i is non-zero. // itob reports whether i is non-zero.

View File

@@ -1,7 +1,7 @@
### 3.5.1. 字符串 ### 3.5.1. 字符串
字符串值也可以用字符串值方式编写, 只要将一系列字序列包含在双引号即可: 字符串值也可以用字符串值方式編寫, 隻要將一係列字序列包含在雙引號卽可:
``` ```
"Hello, 世界" "Hello, 世界"
@@ -9,28 +9,28 @@
![](../images/ch3-04.png) ![](../images/ch3-04.png)
Go言源文件是用UTF8编码, 且Go的文本字符串也以UTF8编码的方式理, 我可以Unicode码点也写到字符串值中. Go言源文件是用UTF8編碼, 且Go的文本字符串也以UTF8編碼的方式理, 我可以Unicode碼點也寫到字符串值中.
在一个双引号包含的字符串值中, 可以用以反斜杠\开头的转义序列插入任意的数据. 下面换行, 回车和 制表符等常的ASCII控制代码的转义方式: 在一箇雙引號包含的字符串值中, 可以用以反斜槓\開頭的轉義序列插入任意的數據. 下麪換行, 迴車和 製錶符等常的ASCII控製代碼的轉義方式:
``` ```
\a 响铃 \a 響鈴
\b 退格 \b 退格
\f 换页 \f 換頁
\n \n
\r 回车 \r 迴車
\t 制表 \t 製錶
\v 垂直制表 \v 垂直製錶
\' 单引号 (用在 '\'' 形式的rune符号面值中) \' 單引號 (用在 '\'' 形式的rune符號麪值中)
\" 双引号 (用在 "..." 形式的字符串值中) \" 雙引號 (用在 "..." 形式的字符串值中)
\\ 反斜 \\ 反斜
``` ```
可以通十六进制或八进制转义在字符串值包含任意的字. 一十六进制的转义是 \xhh, 其中两个h表示十六进制数字(大或小都可以). 一个八进制转义是 \ooo, 包含三个八进制的o字(0到7), 但是不能超\377. 每一个单一的字节表达一个特定的值. 稍后我们将看到如何将一个Unicode码点写到字符串值中. 可以通十六進製或八進製轉義在字符串值包含任意的字. 一十六進製的轉義是 \xhh, 其中兩箇h錶示十六進製數字(大或小都可以). 一箇八進製轉義是 \ooo, 包含三箇八進製的o字(0到7), 但是不能超\377. 每一箇單一的字節錶達一箇特定的值. 稍後我們將看到如何將一箇Unicode碼點寫到字符串值中.
原生的字符串值形式是 `...`, 使用反引 ``` 代替双引号. 在原生的字符串值中, 没有转义操作; 全部的容都是字的意思, 包含退格和行, 因此一程序中的原生字符串值可能跨越多行. 唯一的特殊理是是删除回车以保在所有平上的值都是一的, 包括那些把回车也放入文本文件的系统. 原生的字符串值形式是 `...`, 使用反引 ``` 代替雙引號. 在原生的字符串值中, 沒有轉義操作; 全部的容都是字的意思, 包含退格和行, 因此一程序中的原生字符串值可能跨越多行. 唯一的特殊理是是刪除迴車以保在所有平上的值都是一的, 包括那些把迴車也放入文本文件的係統.
原生字符串值用于编写正则表达式会很方便, 因为正则表达式往往包含很多反斜. 原生字符串面值同时广泛应用于HTML模, JSON值, 命令行提示信息, 以及那些需要展到多行的景. 原生字符串值用於編寫正則錶達式會很方便, 因為正則錶達式往往包含很多反斜. 原生字符串麪值衕時廣氾應用於HTML模, JSON值, 命令行提示信息, 以及那些需要展到多行的景.
```Go ```Go
const GoUsage = `Go is a tool for managing Go source code. const GoUsage = `Go is a tool for managing Go source code.

View File

@@ -1,13 +1,13 @@
### 3.5.2. Unicode ### 3.5.2. Unicode
在很久以前, 世界比较简单的, 起码计算机就只有一ASCII字符集: 美信息交换标准代码. ASCII, 更准确地说是美的ASCII, 使用 7bit 来表示 128 字符: 包含英文字母的大小, 字, 各种标点符号和设置控符. 对于早期的计算机程序, 些足了, 但是这也导致了世界上很多其他地的用户无法直接使用自己的书写系统. 着互联网的发展, 混合多种语言的数据变了很常. 如何有效处理这些包含了各种语言的富多样的数据呢? 在很久以前, 世界比較簡單的, 起碼計算機就隻有一ASCII字符集: 美信息交換標準代碼. ASCII, 更準確地說是美的ASCII, 使用 7bit 來錶示 128 字符: 包含英文字母的大小, 字, 各種標點符號和設置控符. 對於早期的計算機程序, 些足了, 但是這也導緻了世界上很多其他地的用戶無法直接使用自己的書寫係統. 着互聯網的發展, 混閤多種語言的數據變了很常. 如何有效處理這些包含了各種語言的富多樣的數據呢?
答案就是使用Unicode(unicode.org), 它收集了这个世界上所有的书写系统, 包括重音符和其他音符, 制表符和回车符, 有很多神秘符号, 每个符号都分配一Unicode码点, Unicode码点对应Go言中的rune型. 答案就是使用Unicode(unicode.org), 它收集了這箇世界上所有的書寫係統, 包括重音符和其他音符, 製錶符和迴車符, 有很多神祕符號, 每箇符號都分配一Unicode碼點, Unicode碼點對應Go言中的rune型.
第八版本的Unicode标准收集了超120,000字符, 涵盖超过100种语言. 些在计算机程序和数据中是如何体现的那? 通用的示一Unicode码点的数据类型是int32, 也就是Go言中rune对应的类型; 它的同义词rune符文正是这个意思. 第八版本的Unicode標準收集了超120,000字符, 涵蓋超過100種語言. 些在計算機程序和數據中是如何體現的那? 通用的示一Unicode碼點的數據類型是int32, 也就是Go言中rune對應的類型; 它的衕義詞rune符文正是這箇意思.
可以将一个符文序列表示为一个int32序列. 这种编码方式叫UTF-32或UCS-4, 每Unicode码点都使用同样的大小32bit来表示. 这种方式比较简单统一, 它会浪费很多存储空间, 因为大数据计算机可读的文本是ASCII字符, 本来每个ASCII字符需要8bit或1字就能示. 使是常用的字符也远少于65,536, 也就是用16bit编码方式就能表达常用字符. 但是, 有更好的编码方法? 可以將一箇符文序列錶示為一箇int32序列. 這種編碼方式叫UTF-32或UCS-4, 每Unicode碼點都使用衕樣的大小32bit來錶示. 這種方式比較簡單統一, 它會浪費很多存儲空間, 因為大數據計算機可讀的文本是ASCII字符, 本來每箇ASCII字符需要8bit或1字就能示. 使是常用的字符也遠少於65,536, 也就是用16bit編碼方式就能錶達常用字符. 但是, 有更好的編碼方法?

View File

@@ -1,9 +1,9 @@
### 3.5.5. 字符串和字的转换 ### 3.5.5. 字符串和字的轉換
除了字符串, 字符, 字间的转换, 字符串和值之间的转换也比较常见. 由 strconv 包提供这类转换功能. 除了字符串, 字符, 字間的轉換, 字符串和值之間的轉換也比較常見. 由 strconv 包提供這類轉換功能.
将一个整数转为字符串, 一方法是用 fmt.Sprintf; 另一方法是用 strconv.Itoa(“整到ASCII”): 將一箇整數轉為字符串, 一方法是用 fmt.Sprintf; 另一方法是用 strconv.Itoa(“整到ASCII”):
```Go ```Go
x := 123 x := 123
@@ -11,28 +11,28 @@ y := fmt.Sprintf("%d", x)
fmt.Println(y, strconv.Itoa(x)) // "123 123" fmt.Println(y, strconv.Itoa(x)) // "123 123"
``` ```
FormatInt和FormatUint可以用不同的进制来格式化字: FormatInt和FormatUint可以用不衕的進製來格式化字:
```Go ```Go
fmt.Println(strconv.FormatInt(int64(x), 2)) // "1111011" fmt.Println(strconv.FormatInt(int64(x), 2)) // "1111011"
``` ```
fmt.Printf 函的 %b, %d, %u, 和 %x 等参数提供功能往往比strconv 包的 Format 函方便很多, 特是在需要包含附加信息的候: fmt.Printf 函的 %b, %d, %u, 和 %x 等參數提供功能往往比strconv 包的 Format 函方便很多, 特是在需要包含附加信息的候:
```Go ```Go
s := fmt.Sprintf("x=%b", x) // "x=1111011" s := fmt.Sprintf("x=%b", x) // "x=1111011"
``` ```
如果要将一个字符串解析为整数, 可以使用 strconv 包的 Atoi 或 ParseInt 函, 有用解析无符号整数的 ParseUint 函: 如果要將一箇字符串解析為整數, 可以使用 strconv 包的 Atoi 或 ParseInt 函, 有用解析無符號整數的 ParseUint 函:
```Go ```Go
x, err := strconv.Atoi("123") // x is an int x, err := strconv.Atoi("123") // x is an int
y, err := strconv.ParseInt("123", 10, 64) // base 10, up to 64 bits y, err := strconv.ParseInt("123", 10, 64) // base 10, up to 64 bits
``` ```
ParseInt 函的第三个参数是用指定整型的大小; 例如16示int16, 0则表示int. 在任何情下, 返回的结果 y 是 int64 型, 你可以通过强制类型转换将它转为更小的整数类型. ParseInt 函的第三箇參數是用指定整型的大小; 例如16示int16, 0則錶示int. 在任何情下, 返迴的結果 y 是 int64 型, 你可以通過強製類型轉換將它轉為更小的整數類型.
候也使用 fmt.Scanf 解析入的字符串和字, 特别是当字符串和字混在一行的候, 它可以灵活处理不完整或不规则的输入. 候也使用 fmt.Scanf 解析入的字符串和字, 特彆是噹字符串和字混在一行的候, 它可以靈活處理不完整或不規則的輸入.

View File

@@ -1,8 +1,8 @@
## 3.5. 字符串 ## 3.5. 字符串
字符串是一不可改的字序列. 字符串可以包含任意的数据, 包括字值0, 但是通常包含人类可读的文本. 文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列, 我们稍后会详细讨论这个问题. 字符串是一不可改的字序列. 字符串可以包含任意的數據, 包括字值0, 但是通常包含人類可讀的文本. 文本字符串通常被解釋為採用UTF8編碼的Unicode碼點(rune)序列, 我們稍後會詳細討論這箇問題.
置的 len 函可以返回一个字符串的字节数目(不是rune字符目), 索引操作 s[i] 返第i个字节的字值, i 必须满足 0 ≤ i< len(s) 条件约. 置的 len 函可以返迴一箇字符串的字節數目(不是rune字符目), 索引操作 s[i] 返第i箇字節的字值, i 必須滿足 0 ≤ i< len(s) 條件約.
```Go ```Go
s := "hello, world" s := "hello, world"
@@ -12,23 +12,23 @@ fmt.Println(s[0], s[7]) // "104 119" ('h' and 'w')
Attempting to access a byte outside this range results in a panic: Attempting to access a byte outside this range results in a panic:
如果视图访问超出字符串范围的字节将会导致panic常: 如果視圖訪問超齣字符串範圍的字節將會導緻panic常:
```Go ```Go
c := s[len(s)] // panic: index out of range c := s[len(s)] // panic: index out of range
``` ```
第i个字节并不一定是字符串的第i字符, 因此对于非ASCII字符的UTF8编码会要两个或多个字节. 们简单说下字符的工作方式. 第i箇字節並不一定是字符串的第i字符, 因此對於非ASCII字符的UTF8編碼會要兩箇或多箇字節. 們簡單說下字符的工作方式.
子字符串操作s[i:j]原始的s字符串的第i个字节开始到第j个字节(不包含j本身)生成一新字符串. 生成的子字符串包含 j-i 个字节. 子字符串操作s[i:j]原始的s字符串的第i箇字節開始到第j箇字節(不包含j本身)生成一新字符串. 生成的子字符串包含 j-i 箇字節.
```Go ```Go
fmt.Println(s[0:5]) // "hello" fmt.Println(s[0:5]) // "hello"
``` ```
同样, 如果索引超字符串范围或者j小i的话将导致panic. 衕樣, 如果索引超字符串範圍或者j小i的話將導緻panic.
不管i是j都可能被忽略, 当它们被忽略时将采用0作为开始位置, len(s) 接受的位置. 不管i是j都可能被忽略, 噹它們被忽略時將採用0作為開始位置, len(s) 接受的位置.
```Go ```Go
fmt.Println(s[:5]) // "hello" fmt.Println(s[:5]) // "hello"
@@ -36,16 +36,16 @@ fmt.Println(s[7:]) // "world"
fmt.Println(s[:]) // "hello, world" fmt.Println(s[:]) // "hello, world"
``` ```
其中 + 操作符将两个字符串链接构造一新字符串: 其中 + 操作符將兩箇字符串鏈接構造一新字符串:
```Go ```Go
fmt.Println("goodbye" + s[5:]) // "goodbye, world" fmt.Println("goodbye" + s[5:]) // "goodbye, world"
``` ```
字符串可以用 == < 行比; 较通过逐个字节比较完成的, 因此比较的结果是字符串自然编码的顺. 字符串可以用 == < 行比; 較通過逐箇字節比較完成的, 因此比較的結果是字符串自然編碼的順.
字符串的值是不可的: 字符串包含的字序列永远不会被改, 然我也可以给一个字符串量分配一新字符串值. 可以像下面这样将一个字符串追加到另一字符串 字符串的值是不可的: 字符串包含的字序列永遠不會被改, 然我也可以給一箇字符串量分配一新字符串值. 可以像下麪這樣將一箇字符串追加到另一字符串
```Go ```Go
s := "left foot" s := "left foot"
@@ -53,31 +53,31 @@ t := s
s += ", right foot" s += ", right foot"
``` ```
这并不会导致原始的字符串值被改, 但是 s 将因为 += 句持有一新的字符串值, 但是 t 依然是包含原先的字符串值. 這並不會導緻原始的字符串值被改, 但是 s 將因為 += 句持有一新的字符串值, 但是 t 依然是包含原先的字符串值.
```Go ```Go
fmt.Println(s) // "left foot, right foot" fmt.Println(s) // "left foot, right foot"
fmt.Println(t) // "left foot" fmt.Println(t) // "left foot"
``` ```
字符串是不可改的, 因此尝试修改字符串内部数据的操作是被禁止的: 字符串是不可改的, 因此嘗試脩改字符串內部數據的操作是被禁止的:
```Go ```Go
s[0] = 'L' // compile error: cannot assign to s[0] s[0] = 'L' // compile error: cannot assign to s[0]
``` ```
性意味如果两个字符串共享相的底层数据是安全的, 使得复制任何度的字符串代是低廉的. 同样, 字符串 s 对应的子字符串 s[7:] 也可以安全地共享相同的内, 因此字符串切片操作代也是低廉的. 这两种情况下都有必要分配新的. 3.4 演示了一字符串和两个字串共享相的底层数据. 性意味如果兩箇字符串共享相的底層數據是安全的, 使得復製任何度的字符串代是低廉的. 衕樣, 字符串 s 對應的子字符串 s[7:] 也可以安全地共享相衕的內, 因此字符串切片操作代也是低廉的. 這兩種情況下都有必要分配新的. 3.4 演示了一字符串和兩箇字串共享相的底層數據.
{% include "./ch3-03-1.md" %} {% include "./ch3-05-1.md" %}
{% include "./ch3-03-2.md" %} {% include "./ch3-05-2.md" %}
{% include "./ch3-03-3.md" %} {% include "./ch3-05-3.md" %}
{% include "./ch3-03-4.md" %} {% include "./ch3-05-4.md" %}
{% include "./ch3-03-5.md" %} {% include "./ch3-05-5.md" %}

View File

@@ -1,4 +1,4 @@
### 3.6.2. 无类型常量 ### 3.6.2. 無類型常量
TODO TODO