很多人喜欢GO语言的原因是简单。Go语言的类型也是设计的如此简单。
预定义类型
Go语言默认定义了一些类型如boolean,numeric和string.这些预定义的类型用于构建其他复杂的类型,例如array,struct,pointer,slice,map,channel等。
命名和未命名
类型可以有一个名字也可以没有名字。
命名的类型可以有他们自己的函数集。
type Map map[string]string
//this is valid
func (m Map) Set(key string, value string){
m[key] = value
}
//this is invalid
func (m map[string]string) Set(key string,value string){
m[key] = value
}
以上代码中,定义了一个方法,使用Map作为接受。如果使用一个没有命名的类型例如map[string]来作为接受那么是非法的。
预定义的类型也叫作命名类型。所以int是命名类型,但是*int或[]int则不是。
基本类型
每个类型都有一个基础类型。预定义类型和类型字符将就是本身的基本类型。
当定义一个新类型的时候,需要提供一个存在的类型。一个新类型会和存在的类型有相同的基本类型。
例如:
type Map map[string]string
type SpecialMap Map
这里,map[string]string的基础类型就是他本身,但是Map和SpecialMap的基本类型是map[string] string
声明的类型不会从存在的类型或基本类型中继承任何方法。但是,复杂类型的接口方法集和元素会保持不变。这主要是考虑到,如果你定义了一个新类型,那么就需要定义一个方法集。
可赋值性
type Mystring string
var str string = "abc"
var my_str MyString = str //gives a compile error
如上代码。
不能将一个不同类型的进行赋值。因为my_str和str的类型是不同的了。哈哈
基本上,赋一个值给变量,值的类型应该和变量类型统一。如果基本类型一致并且其中一个是未命名的也可以赋值。
例如:
package main
import "fmt"
type Person map[string]string
type Job map[string]string
func keys(m map[string]string) (keys []string) {
for key, _ := range m {
keys = append(keys, key)
}
return
}
func name(p Person) string {
return p["first_name"] + " " + p["last_name"]
}
func main(){
var person = Person{"first_name": "Rob", "last_name": "Pike"}
var job = Job{"title": "Commander", "project": "Golang"}
fmt.Printf("%v\n", name(person))
fmt.Printf("%v", name(job)) //this gives a compile error
fmt.Printf("%v\n", keys(person))
fmt.Printf("%v\n", keys(job))
}
这里Person和Job的基本类型是map[string]string. 如果将类型Job的实例传递给函数就会报一个编译错误。但是可以将Job和Person的实例传递给keys函数,因为keys函数是未命名的map[string] string类型。
类型嵌入
当定义一个类型的时候,不会集成类型的方法集。但是,有个方法可以在新类型中嵌入已存在类型方法集。通过在结构类型中使用匿名域的属性。当在结构中定义一个匿名域的时候,所有域和方法会给定义的结构类型。
如下:
package main
type User struct {
Id int
Name string
}
type Employee struct {
User //annonymous field
Title string
Department string
}
func (u *User) SetName(name string) {
u.Name = name
}
func main(){
employee := new(Employee)
employee.SetName("Jack")
}
User类型的域和方法提供给了Employee
因为在Employee结构体中是匿名方式定义的User.
类型转换
基本上,在命名的类型和基本类型之间可以进行转换。
例如:
type Mystring string
var my_str Mystring =Mystring("awesome")
var str string = string(my_str)
和string类型转换不同,所有其他转换只需要修改类型而不需要修改值。
可以将string转换给一个integers的slice或者反过来。
在使用接口和反射时候可以会有更多稳定和复杂的类型操作。
友情链接
http://www.laktek.com/2012/01/27/learning-go-types/
作者:Rob Pike Wiki百科
https://en.wikipedia.org/wiki/Rob_Pike