Goland中Type关键字的几种使用场景

1. 定义结构体

Type 关键字可以用来定义结构体:

type User struct {
	Name string
	age int
}

2. 类型别名

其实就是给原来的类型加一个别名,方便我们后面调用。

type str string
//在下面的代码中str就可以代替string使用了
var str1 str = "我是一个类型别名"
//这里不只是基础类型 结构体(复合类型)也可以使用别名
type (
	I int
	IA []int
	U User
)

以上面的例子来说,后面的代码里 str 在很多场合都可以作为string关键字使用,但是它俩也有不一样的地方,这个我们后面会讲。

3.  定义接口

这里 我们定义一个 Speak 里面 包含一个方法call。

//这里 我们定义一个 Speak 里面 包含一个方法call
type Speak interface {
	call() string
}

4.  定义函数类型

因为在Goland中,函数也是一种数据类型,具有相同参数和返回值的函数,我们认为它们的类型相同。(我们这里的相同指的是:个数、数据类型、顺序全部相同)。

其实,如果你把函数也当做一种类型来看的话,Type的这种使用方式跟我们说的第二种使用方式(类型别名)是一致的。

type handler func(string) int

5 具体使用

接下来我们结合代码来看看它们的使用场景和要注意的点

首先我们定义一个函数,我们将它的参数指定为我们刚刚定义的handler 函数类型

func TestFunc(handler2 handler){
	fmt.Println("这个函数的参数必须为函数类型 handler,并且接下里展示的是handler函数的执行结果")
	//因为handler2 需要一个string 类型的参数我们这里给空串
	handler2("")
}

当我们调用TestFunc的时候,我们需要一个handler类型的参数:

	var handlerFunc handler = func(s string) int {
		return 1
	}
	//这样执行时没问题的
	TestFunc(handlerFunc)

既然上面说了,当函数的参数和返回值类型一致的时候,可以视为同一个类型,我们来看一个例子:

handlerFunc2 := func(s string) int {
		return 2
}

TestFunc(handlerFunc2)

我们没有使用handler,直接定义了一个函数,可以看到在函数的参数和返回值一致的时候,同样可以作为TestFunc的参数。

注意:在绝大多数情况下,类型别名和源类型是等价的,但是也有例外的情况。比如我们在写方法的时候:

请看下面的例子:

func (h handler)call()string{
	return "我是一个函数对象实现的接口"
}
func (s str)call()str{
	return s
}
func (user User) call()str {
	return ""
}

我们分别实现了三个方法,其实就是在别名str(对应string)、handler(对应 func(s string)int 函数类型、User(结构体 别名为U 上面有定义)。

handlerFunc.call()//这样是可以执行的
//但是 下面的写法确实不可以的
handlerFunc2.call()//编译器给出了一个错误"未解析的引用'call'"
//同理
var str1 str = "我是一个string的别名"
str1.call()//这样调用是没有问题的
var str2 string = "我是一个传统的字符串"
str2.call()//编译器报错了
user := User{}
user.call()//也没有问题
user1 := U{}
user1.call()//编译器报错

 这个时候我们可以得出结论:在我们是有Type 定义类型别名(定义函数类型)的时候,他们所实现的方法是不互通的。

 

你可能感兴趣的:(编程语言,go语言,go)