学习GO:接口类型
Interface Types 是Go编程语言中最强大的功能之一,如果使用得当,它可以使代码更容易维护和扩展。根据你的编程经验,这个概念可能有点难以理解,因为你可能是第一次听到这个概念,或者你所熟悉的编程语言没有相应的概念,或者即使有,它的实现方式也与Go的实现方式不同。
Interfaces Types 是类型,因此我们需要清楚地了解什么是 ,Go中支持的类型有哪些。type
什么是类型?
在Go中,一个Type 是表示状态或行为的一种方式。有两种类型。基本类型和复合类型。
基本类型包括你众所周知的类型,这些类型是用来以特定的方式存储数据的,具体来说。
string, 比如说。"hello",numeric,其中包括以integer、float或complex数字表示的数字类型。有一些数字类型是为了描述允许的最大容量和支持的可能值,例如uint8代表一个无符号整数,其容量为8比特。bool,定义了一个布尔值,允许true或false
这些将被视为*"基本 "的* 基本类型,意味着其他类型通过别名使用它们来定义新的类型,这是为了区分它们的目标,但最终它们重用了原始基本类型的能力。例如,byte 类型是uint8 的别名。
复合类型包括一些更复杂的类型,在幕后是由其他多种类型组成的,具体而言。
pointer, 用来保存一个值的内存地址。function, 定义了一个共同工作的语句集合。map,用于将键映射到值的数据结构。array,定义了一个静态的值集合。- **
slice**定义了一个动态大小的数组。 - **
struct**定义了一种创建新的自定义类型的方法,该类型有一个字段集合。 - **
channel**定义了一个用于发送和接收值的管道,以及最后的 interface,是一组方法签名。
函数和方法
使用这些类型来定义变量可以让我们把它们和函数结合起来使用,而函数是用来模块化我们的代码并允许一些重用性。因为Go不是一种面向对象的编程语言,也没有类,所以当我们试图将行为附加到我们的自定义类型时,函数就派上了用场,当我们这样做时,就会引入一个新的概念。方法。
方法是在幕后接收一个特殊的第一个参数的函数。这个参数类型与定义方法的类型相同,其值是调用函数的参数,它在某种程度上被用来模仿面向对象的编程语言对类的作用。
例如,一个表示三种不同优先级的简单类型可以定义为。
type Priority int8
func (p Priority) String() string {
switch int8(p) {
case 0:
return "low"
case 1:
return "high"
}
return "unknown"
}
上面的代码创建了一个名为Priority 的新类型,它使用了int8 基本类型,行为是在实现String 方法后添加的,该方法返回一个代表存储在自定义类型中的值的string 。
为了利用这个行为,我们有几种不同的方法,让我们看看下面的代码。
func main() {
var p Priority = 1
fmt.Println(p.String()) // "high"
fmt.Println(Priority.String(p)) // "high"
fmt.Println(p) // "high"
}
这三种情况的输出都是一样的,但是在这个例子中重要的是如何调用String 这个方法。
p.String():因为这是一个方法调用,变量p在幕后作为第一个参数传递给类型为String的函数Priority,并像往常一样执行。Priority.String(p): 回想一下,方法就是函数,因此我们仍然可以用这种方式对函数进行调用,这种方式肯定是不常见的,但是看到这个调用的动作,就更加明确了前面的说法。方法就是函数。
最后,最后一行fmt.Println 做了一些有趣的事情,因为它没有明确地调用String 。这是怎么做到的呢?这就是接口类型的作用。
什么是接口类型?
Interface Types 是一组方法签名,可以容纳任何实现这些方法的值。实现这组方法的类型会自动与被定义的接口类型兼容,换句话说,与其他编程语言相比,Go中的接口类型是 implicit.
这意味着要实现一个接口的类型不需要像其他语言那样,事先知道接口类型来实现它或扩展它。
接口类型带来了面向对象编程语言的一个特点。多态性。
如果一个类型满足了一组方法的签名,那么该类型就等同于定义了上述方法的接口类型。这就是为什么fmt.Println 中的第三个调用不需要显式调用String ,实现了 fmt.Println的实现定义了一个文档中提到的接口类型。
如果一个操作数实现了String()字符串方法,该方法将被调用以将对象转换为字符串,然后按动词(如果有的话)的要求进行格式化。
具体来说,在这种情况下,在fmt 包中有一个接口类型,叫做 Stringer它定义了我们的Priority 类型所实现的String 方法,最终用于打印出字符串值。
总结
就像我在开始写这篇文章时提到的,接口类型是Go中的一个伟大的功能,它允许我们建立可以处理不同实现的多态代码,但不仅如此,它还允许扩展现有的代码,因为不需要明确定义/输入/扩展接口类型。