回到简体

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,24 +1,24 @@
## 2.5.
## 2.5.
量或表式的型定義了對應存儲值的性特,例如值在存的存大小或者是元素的bit個數),它們在內部是如何表的,是否支持一些操作符,以及它自己關聯的方法集等。
量或表式的型定义了对应存储值的性特,例如值在存的存大小或者是元素的bit个数),它们在内部是如何表的,是否支持一些操作符,以及它自己关联的方法集等。
在任何程序中都存在一些量有着相同的內部結構,但是表示完全不同的概念。例如,一int型的量可以用表示一個循環的迭代索引、或者一個時間戳、或者一文件描述符、或者一月份;一float64型的量可以用表示每秒移動幾米的速度、或者是不同溫度單位下的度;一字符串可以用表示一個密碼或者一個顔色的名
在任何程序中都存在一些量有着相同的内部结构,但是表示完全不同的概念。例如,一int型的量可以用表示一个循环的迭代索引、或者一个时间戳、或者一文件描述符、或者一月份;一float64型的量可以用表示每秒移动几米的速度、或者是不同温度单位下的度;一字符串可以用表示一个密码或者一个颜色的名
個類型聲明語句創建了一新的型名,和現有類型具有相同的底層結構。新命名的型提供了一方法,用分隔不同概念的型,這樣卽使它們底層類型相同也是不兼容的。
个类型声明语句创建了一新的型名,和现有类型具有相同的底层结构。新命名的型提供了一方法,用分隔不同概念的型,这样即使它们底层类型相同也是不兼容的。
```Go
type 型名字 層類
type 型名字 层类
```
類型聲明語句一般出在包一,因此如果新建的型名字的首字符大寫,則在外部包也可以使用。
类型声明语句一般出在包一,因此如果新建的型名字的首字符大写,则在外部包也可以使用。
譯註:對於中文Unicode標誌都作爲小寫字母理,因此中文的命名默不能出;不過国內的用戶針對該問題提出了不同的看法,根RobPike的迴複在Go2中有可能會將中日等字符作大字母理。下面是RobPik在 [Issue763](https://github.com/golang/go/issues/5763) 的迴複
译注:对于中文Unicode标志都作为小写字母理,因此中文的命名默不能出;不过国内的用户针对该问题提出了不同的看法,根RobPike的回复在Go2中有可能会将中日等字符作大字母理。下面是RobPik在 [Issue763](https://github.com/golang/go/issues/5763) 的回复
> A solution that's been kicking around for a while:
>
> For Go 2 (can't do it before then): Change the definition to “lower case letters and _ are package-local; all else is exported”. Then with non-cased languages, such as Japanese, we can write 日本 for an exported name and _日本 for a local name. This rule has no effect, relative to the Go 1 rule, with cased languages. They behave exactly the same.
> For Go 2 (can't do it before then): Change the definition to “lower case letters and _ are package-local; all else is exported”. Then with non-cased languages, such as Japanese, we can write 日本 for an exported name and _日本 for a local name. This rule has no effect, relative to the Go 1 rule, with cased languages. They behave exactly the same.
爲了説明類型聲明,我們將不同溫度單位分别定義爲不同的型:
为了说明类型声明,我们将不同温度单位分别定义为不同的型:
<u><i>gopl.io/ch2/tempconv0</i></u>
```Go
@@ -27,13 +27,13 @@ package tempconv
import "fmt"
type Celsius float64 // 攝氏溫
type Fahrenheit float64 // 華氏溫
type Celsius float64 // 摄氏温
type Fahrenheit float64 // 华氏温
const (
AbsoluteZeroC Celsius = -273.15 // 絶對零度
FreezingC Celsius = 0 // 結冰點溫
BoilingC Celsius = 100 // 沸水
AbsoluteZeroC Celsius = -273.15 // 绝对零度
FreezingC Celsius = 0 // 结冰点温
BoilingC Celsius = 100 // 沸水
)
func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
@@ -41,13 +41,13 @@ func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) }
```
們在這個包聲明了兩種類Celsius和Fahrenheit分别對應不同的溫度單位。它們雖然有着相同的底層類型float64但是它是不同的數據類型,因此它不可以被相互比或混在一個表達式運算。刻意區分類型,可以避免一些像意中使用不同位的度混合計算導致的錯誤;因此需要一個類似Celsius(t)或Fahrenheit(t)形式的顯式轉型操作才能float64轉爲對應的類型。Celsius(t)和Fahrenheit(t)是類型轉換操作,它們併不是函數調用。類型轉換不會改變值本身,但是使它們的語義發生變化。另一方面CToF和FToC兩個函數則是對不同溫度單位下的溫度進行換算,它們會返迴不同的值。
们在这个包声明了两种类Celsius和Fahrenheit分别对应不同的温度单位。它们虽然有着相同的底层类型float64但是它是不同的数据类型,因此它不可以被相互比或混在一个表达式运算。刻意区分类型,可以避免一些像意中使用不同位的度混合计算导致的错误;因此需要一个类似Celsius(t)或Fahrenheit(t)形式的显式转型操作才能float64转为对应的类型。Celsius(t)和Fahrenheit(t)是类型转换操作,它们并不是函数调用。类型转换不会改变值本身,但是使它们的语义发生变化。另一方面CToF和FToC两个函数则是对不同温度单位下的温度进行换算,它们会返回不同的值。
對於每一個類型T都有一個對應的類型轉換操作T(x)用於將x轉爲T類型譯註如果T是指針類型,可能需要用小括弧包T比如`(*int)(0)`)。隻有當兩個類型的底層基礎類型相同,才允許這種轉型操作,或者是者都是指向相同底層結構的指針類型,這些轉換隻改變類型而不會影響值本身。如果x是可以賦值給T類型的值,那x必然也可以被轉爲T類型,但是一般沒有這個必要。
对于每一个类型T都有一个对应的类型转换操作T(x)用于将x转为T类型译注如果T是指针类型,可能需要用小括弧包T比如`(*int)(0)`)。只有当两个类型的底层基础类型相同,才允许这种转型操作,或者是者都是指向相同底层结构的指针类型,这些转换只改变类型而不会影响值本身。如果x是可以赋值给T类型的值,那x必然也可以被转为T类型,但是一般没有这个必要。
數值類型之間的轉型也是允的,且在字符串和一些特定型的slice之也是可以轉換的,在下一章我們會看到這樣的例子。這類轉換可能改值的表。例如,將一個浮點數轉爲整數將丟棄小數部分,將一個字符串轉爲`[]byte`型的slice將拷貝一個字符串數據的副本。在任何情下,運行時不會發生轉換失敗的錯誤(譯註: 錯誤隻會發生在編譯階段)。
数值类型之间的转型也是允的,且在字符串和一些特定型的slice之也是可以转换的,在下一章我们会看到这样的例子。这类转换可能改值的表。例如,将一个浮点数转为整数将丢弃小数部分,将一个字符串转为`[]byte`型的slice将拷贝一个字符串数据的副本。在任何情下,运行时不会发生转换失败的错误(译注: 错误只会发生在编译阶段)。
層數據類型決定了內部結構和表方式,也定是否可以像底層類型一樣對內置運算符的支持。意味着Celsius和Fahrenheit型的算術運算行和底的float64型是一的,正如我所期望的那
层数据类型决定了内部结构和表方式,也定是否可以像底层类型一样对内置运算符的支持。意味着Celsius和Fahrenheit型的算术运算行和底的float64型是一的,正如我所期望的那
```Go
fmt.Printf("%g\n", BoilingC-FreezingC) // "100" °C
@@ -56,7 +56,7 @@ fmt.Printf("%g\n", boilingF-CToF(FreezingC)) // "180" °F
fmt.Printf("%g\n", boilingF-FreezingC) // compile error: type mismatch
```
較運算符`==``<`也可以用來比較一個命名型的量和另一有相同型的量,或有着相同底層類型的未命名型的值之做比。但是如果兩個值有着不同的型,不能直接行比
较运算符`==``<`也可以用来比较一个命名型的量和另一有相同型的量,或有着相同底层类型的未命名型的值之做比。但是如果两个值有着不同的型,不能直接行比
```Go
var c Celsius
@@ -67,19 +67,19 @@ fmt.Println(c == f) // compile error: type mismatch
fmt.Println(c == Celsius(f)) // "true"!
```
意最後那個語句。管看起想函數調但是Celsius(f)是類型轉換操作,它併不會改變值,僅僅是改值的型而已。測試爲眞的原因是因c和g都是零值。
意最后那个语句。管看起想函数调但是Celsius(f)是类型转换操作,它并不会改变值,仅仅是改值的型而已。测试为真的原因是因c和g都是零值。
命名的型可以提供書寫方便,特别是可以避免一遍又一遍地書寫複雜類型譯註例如用匿名的結構體定義變量。雖然對於像float64這種簡單的底層類型沒有簡潔很多但是如果是複雜的類型將會簡潔很多特别是我們卽將討論的結構體類型。
命名的型可以提供书写方便,特别是可以避免一遍又一遍地书写复杂类型译注例如用匿名的结构体定义变量。虽然对于像float64这种简单的底层类型没有简洁很多但是如果是复杂的类型将会简洁很多特别是我们即将讨论的结构体类型。
命名類型還可以爲該類型的值定新的行爲。這些行表示爲一組關聯到該類型的函集合,我們稱爲類型的方法集。我們將在第六章中討論方法的細節,這里值説寫簡單用法。
命名类型还可以为该类型的值定新的行为。这些行表示为一组关联到该类型的函集合,我们称为类型的方法集。我们将在第六章中讨论方法的细节,这里值说写简单用法。
下面的聲明語Celsius型的參數c出在了函名的前面,表示明的是Celsius型的一叫名叫String的方法方法返迴該類型對象c着°C溫度單位的字符串:
下面的声明语Celsius型的参数c出在了函名的前面,表示明的是Celsius型的一叫名叫String的方法方法返回该类型对象c着°C温度单位的字符串:
```Go
func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
```
許多類型都會定義一個String方法爲當使用fmt包的打印方法時,將會優先使用該類型對應的String方法返迴的結果打印,我們將在7.1節講述。
许多类型都会定义一个String方法为当使用fmt包的打印方法时,将会优先使用该类型对应的String方法返回的结果打印,我们将在7.1节讲述。
```Go
c := FToC(212.0)