前言:
go语言的类型系统
基础类型,如byte、int、bool、float等;
复合类型,如数组、结构体、指针等;可以指向任意对象的类型(Any类型);
值语义和引用语义;
面向对象,即所有具备面向对象特征(比如成员方法)的类型;
接口。
Go语言和C语言一样,类型都是基于值传递的,如果想要引用该值,则引用即可,减少了使用指针的空间浪费;
如果想要修改该值,则需要传递指针。
Java中存在两套完全独立的类型系统:
一套是值类型系统,主要是基本类型, 如byte、int、boolean、char、double等,这些类型基于值语义;
一套是以Object类型为根的对象类型系统,这些类型可以定义成员变量和成员方法,可以有虚函数,基于引用语义,只允许在堆上创建(通过使用关键字new)
Java语言中的Any类型就是整个对象类型系统的根——java.lang.Object类型,只有对象类型系统中的实例才可以被Any类型引用。
值类型想要被Any类型引用,需要装箱(boxing)过程,比如int类型需要装箱成为Integer类型。
另外,只有对象类型系统中的类型才可以实现接口,具体方法是让该类型从要实现的接口继承
Go语言中的大多数类型都是值语义,并且都可以包含对应的操作方法。
任何类型都可以被Any类型引用。Any类型就是空接口, 即interface{}
而在实现某个接口时,无需从该接口继承(事实上,Go语言根本就不支持面向对象思想中的继承语法),只需要实现该接口要求的所有方法即可
为类型添加方法:
type Integer int func (a Integer) Less(b Integer) bool { // 面向对象 return a < b } func Integer_Less(a Integer, b Integer) bool { // 面向过程 return a < b } a.Less(2) // 面向对象的用法 Integer_Less(a, 2) // 面向过程的用法
Go语言和C语言一样,类型都是基于值传递的。要想修改变量的值,只能传递指针
func (a *Integer) Add(b Integer) { *a += b }
值语义和引用语义:
go语言中大部分都为值类型,但是有些特例
数组切片:指向数组(array)的一个区间。
map:极其常见的数据结构,提供键值查询能力。
channel:执行体(goroutine)间的通信设施。
接口(interface):对一组满足某个契约的类型的抽象。
因为其本质都是一个区间
如数组切片
type slice struct { first *T len int cap int }
go语言中的结构体与类相同,但是同样,不能继承,可以有组合(composition)特性
匿名组合:
type Base struct { Name string } func (base *Base) Foo() { ... } func (base *Base) Bar() { ... } type Foo struct { Base ... } func (foo *Foo) Bar() { foo.Base.Bar() }
Foo 类,该类从 Base 类“继承”并改写了 Bar() 方法,如果没有改写该方法,则调用Foo.bar()与调用Foo.Base.bar()效果一致
2.在Go中,可以随心修改内存布局
type Foo struct { ... // 其他成员 Base }
3.还可以以指针方式从一个类型“派生”
type Foo struct{ *Base ... }
匿名组合总体来说解决了C++中的虚基类,其好处在于,可以隐藏掉其组合的类X,不必关心其的实现机制。但是同时,组合的类X无法访问该类A的成员变量,因为在写X的时候,A还没有存在,这也是需要考虑的部分
问题:
变量重名,解决方法1, 变量隐藏,2,报错
初始化:
在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,例如bool类型的零值为false,int类型的零值为0,string类型的零值为空字符串
type Rect struct { x, y float64 width, height float64 }
rect1:=new(Rect) rect2:=&Rect{} rect3:=&Rect{0, 0, 100, 200} rect4:=&Rect{width: 100, height: 200}
由于Go语言没有构造函数(Go语言也没有继承概念),所以使用NewXXX作为构造函数初始化类
func NewRect(x, y, width, height float64) *Rect { return &Rect{x, y, width, height} }
开发者也不需要分析在使用了new之后到底背后发生了多少事情。在Go语言中,一切要发生的事情都直接可以看到
可见性:
符号定义为以大写字母开头,则该成员可以在包外被访问
若是小写字母开头,则之能够在包内被访问
总结,go语言中符号的可访问性是指 包一级的,在同一个包下的类之间可以无限制访问;若是同c++一样是类型一级的,则类与类之间的访问需要加上关键字friend
有疑问加站长微信联系(非本文作者)