Go语言2-类型

类型系统是指一个语言的类型体系结构,一个典型的类型系统通常包含如下基本内容:

  1. 基础类型: byte、int、bool、float等
  2. 复合类型: 如数组、结构体、指针等;
  3. 可以指向任意对象的类型(Any类型)
  4. 值语义和引用语义
  5. 对象
  6. 接口

GO 是一种静态编译型语言,编译器需要在编译时知道每个值的类型,以便运行前检查,编译时优化代码。go允许用户自定义类型,有两种方式,最常用使用关键词struct声明结构类型。

自定义类型

strunct声明结构类型

例如s,声明一种类型user:

type user struct {
	name string
	email string
	ext int
	privileged bool
}

使用:

var zz user

声明user类型zz,并没有初始化,自动使用默认类型初始化,如:0,“”,false。也可以在声明时初始化,如下:

thoreau := user{
		name: "thoreau",
		email: "zz.thoreau@g.com",
		ext:1,
		privileged: false,
	}

print thoreau –> {thoreau zz.thoreau@g.com 1 false}

上述初始化方式需要每个属性,也可以按照自动顺序初始化:

lisa := user{"Lisa", "lisa@email.com", 123, true}
fmt.Println(lisa)

结果:{Lisa lisa@email.com 123 true}

使用已有类型声明

基于一个已有的类型,将其作为新类型的类型说明,有点像类型赋值,但是,他们不是同一类型,不能相互赋值,下面的示例就会编译出错。

package main
     type Duration int64
     func main() {
         var dur Duration
         dur = int64(1000)
}

方法

方法能给用户定义的类型添加新的行为。方法实际上也是函数,只是在声明时,在关键字func 和方法之间加了一个参数。

关键字 func 和函数之间的参数被作接收者,将函数与接收者的类型绑在一起。如果一个函数有接收者,这个函数就被称为方法。

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

package main
import (
	"fmt"
)
func main() {
	lisa := user{"Lisa", "lisa@email.com", 123, true}
	lisa.printUser(",hello!")
	fmt.Println(lisa.extLess100())
}
type user struct {
	name string
	email string
	ext int
	privileged bool
}
func (u user) printUser(s string) {
	fmt.Println(u.name,s)
}
func (u user) extLess100()  bool{
	return u.ext < 100
}

Lisa ,hello! false

上面的示例表示,声明了一种类型user,有方法printUser和extLess100。可以看出有,跟java中类和方法的区别是,方法可以定义在类型外,方法需要指明类型绑定,返回值放到了最后。具体来说,方法绑定对象(接收者),函数只跟包有关系。

值接收者和指针接收者

go定义了两种接收者:值接收者和指针接收者,上面示例属于值接收者。使用值接收者,使用的其实是接收者的一个副本,任何操作都不会影响原来的类型变量。如果是指针传递,操作的是指针副本,但副本也指向同一个类型变量,所以会改变原来的类型,如下:

package main
import (
	"fmt"
)
func main() {
	p:=person{name:"go"}
	p.modify() //值接收者,修改无效
	fmt.Println(p.toString())
	p.modifyOrigin()
	fmt.Println(p.toString())
}
type person struct {
	name string
}
func (p person) toString() string{
	return "the person name is "+p.name
}
func (p person) modify(){
	p.name = "thoreau"
}
func (p *person) modifyOrigin(){
	p.name = "thoreau"
}

the person name is go the person name is thoreau

从结果看出,modify方法不改变原类型变量,但modifyOrigin改变了,区别就是使用了*persion指针传递。

多值返回

和函数一样,方法支持多返回值

可变参数

函数方法的参数,可以是任意多个,这种我们称之为可以变参数。使用...表示。

func main() {
	fmt.Println(add(1, 2, 3))
	fmt.Println(add(1, 2, 3, 4))
}
func add(x ... int) int {
	var y int = 1
	for _, v := range x {
		y = y + v
	}
	return y
}

7 11

CONTENTS