golang中的类型系统-创新互联

序:

成都创新互联公司致力于互联网品牌建设与网络营销,包括网站设计制作、成都做网站、SEO优化、网络推广、整站优化营销策划推广、电子商务、移动互联网营销等。成都创新互联公司为不同类型的客户提供良好的互联网应用定制及解决方案,成都创新互联公司核心团队十年专注互联网开发,积累了丰富的网站经验,为广大企业客户提供一站式企业网站建设服务,在网站建设行业内树立了良好口碑。

在Java语言中,存在两套完全独立的类型系统:一套是值类型系统,主要是基本类型,如byte int boolean char double等,这些类型基于值语义;一套是以object类型为根的对象类型系统,这些类型可以定义成员变量和成员方法,可以有虚函数,基于引用语义,只允许在堆上创建(通过使用关键字new)。Java语言中的Any类型就是整个对象系统的根——java.lang.Object类型,只有对象类型系统中的实例才可以被Any类型引用。值类型想要被Any类型引用,需要装箱(boxing)过程,比如int类型需要装箱成为Integer类型。另外,只有对象类型系统中的类型才可以实现接口,具体方法是让该类型从要实现的接口继承。

相比之下,Go语言中的大多数类型都是值语义,并且都可以包含对应的操作方法。在需要的时候,你可以给任何类型(包括内置类型)"增加"新方法。而在实现某个接口时,无需从该接口集成(事实上,GO语言根本就不支持面向对象思想中的继承语法),只需要实现该接口要求的所有方法即可。任何类型都可以被Any类型引用。Any类型就是空接口,即interface()。

为类型添加方法:

在GO语言中,你可以给任意类型(包括内置类型,但不包括指针类型)添加相应的方法,例如:

type Integer int

func (a Integer) Less (b Integer) bool {

   return a < b

}

在这个例子中,我们定义了一个新类型Integer,它和int没有本质不同,只是它为内置的int类型增加了个新方法Less()。

这样实现了Integer后,就可以让整型像一个普通类一样使用:

func main() {

   var a Integer = 1

   if a.Less(2) {

       fmt.Println(a, "Less 2")

   }

}

值语义和引用语义:

值语义和引用语义的差别在于赋值,比如下面的例子:

b = a

b.Modify()

如果b的修改不会影响a的值,那么此类型属于值类型。如果会影响a的值,那么此类型是引用类型。

GO语言中大多数类型都基于值语义,包括:

基本类型,如byte int bool float32 float64 和 string 等

复合类型,如数组(array) 结构体(struct) 和指针(pointer) 等

GO语言中类型的值语义表现的非常彻底。之所以这么说,是因为数组。

GO语言中的数组和基本类型没有区别,是很纯粹的值类型,例如:

var a = [3]int{1,2,3}

var b = a

b[1]++

fmt.Println(a, b)

该程序的运行结果如下:

[1 2 3] [1 3 3]

这表明b=a赋值语句是数组内容的完整复制。要想表达引用,需要用指针:

var a = [3]int{1, 2, 3}

var b = &a

b[1]++

fmt.Println(a, *b)

该程序的运行结果如下:

[1 3 3] [1 3 3]

这表明b=&a赋值语句是数组内容的引用。变量b的类型不是[3]int,而是*[3]int类型。

GO语言中4个类型比较特别,看起来像引用类型,如下所示。

数组切片:指向数组(array)的一个区间。

map:极其常见的数据结构,提供键值查询能力。

channel:执行体(goroutine)间的通信设施。

接口(interface):对一组满足某个契约的类型的抽象。

但是这并不影响我们将GO语言类型看做值语义。下面我们来看看这4个类型。

数组切片本质上是一个区间,你可以大致将[]T表示为:

type slice struct {

   first *T

   len int

   cap int

}

因为数组切片是指向数组的指针,所以可以改变所指向的数组元素并不奇怪。数组切片类型本身的赋值仍然是值语义。

结构体:

GO语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括集成在内的大量面向对象特性,只保留了组合(composition)这个最基础的特性。

上面我们说到,所有的Go语言类型(指针类型除外)都可以有自己的方法。在这个背景下,Go语言的结构体只是很普通的复合类型,平淡无奇。例如,我们要定义一个矩形类型:

type Rect struct {

   x, y float64

   width, height float64

}

然后我们定义成员方法Area()来计算矩形的面积:

func (r *Rect) Area() float64 {

   return r.width * r.height

}

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


网站标题:golang中的类型系统-创新互联
新闻来源:http://pwwzsj.com/article/iessd.html