Golang 接口

Golang 接口

Go语言的接口与其他语言不同。在Go语言中,接口是一种自定义类型,用于指定一组或多个方法签名,接口是抽象的,所以你不允许创建接口的实例。但是你可以创建一个接口类型的变量,这个变量可以被分配一个具体类型的值,这个值具有接口要求的方法。或者换句话说,接口是一个方法的集合,同时也是一个自定义类型。

如何创建一个接口

在Go语言中,你可以使用以下语法来创建一个接口。

type interface_name interface{

// Method signatures

}

比如说

// Creating an interface
type myinterface interface{

// Methods
fun1() int
fun2() float64
}

在这里,接口名称被包含在类型和接口关键字之间,方法签名被包含在大括号之间。

如何实现接口

在Go语言中,要实现一个接口,必须实现接口中声明的所有方法。Go语言的接口是隐式实现的。和其他语言一样,它不包含任何特定的关键字来实现一个接口。正如下面的例子所示。

Golang中的接口

例子

// Golang program illustrates how
// to implement an interface
package main
  
import "fmt"
  
// Creating an interface
type tank interface {
  
    // Methods
    Tarea() float64
    Volume() float64
}
  
type myvalue struct {
    radius float64
    height float64
}
  
// Implementing methods of
// the tank interface
func (m myvalue) Tarea() float64 {
  
    return 2*m.radius*m.height +
        2*3.14*m.radius*m.radius
}
  
func (m myvalue) Volume() float64 {
  
    return 3.14 * m.radius * m.radius * m.height
}
  
// Main Method
func main() {
  
    // Accessing elements of
    // the tank interface
    var t tank
    t = myvalue{10, 14}
    fmt.Println("Area of tank :", t.Tarea())
    fmt.Println("Volume of tank:", t.Volume())
}

输出

Area of tank : 908
Volume of tank: 4396

重要要点

  • 接口的零值是nil。
  • 当一个接口包含零方法时,这种类型的接口被称为空接口。所以,所有的类型都实现了空接口。

语法:

interface{}
  • 接口类型:接口有两种类型,一种是静态类型,另一种是动态类型。静态类型是接口本身,例如下面例子中的tank。但是接口没有静态值,所以它总是指向动态值。

一个接口类型的变量包含实现该接口的类型的值,所以该类型的值被称为动态值,其类型是动态类型。它也被称为具体值和具体类型。

示例:

// Go program to illustrate the concept
// of dynamic values and types
package main
  
import "fmt"
  
// Creating an interface
type tank interface {
  
    // Methods
    Tarea() float64
    Volume() float64
}
  
func main() {
  
    var t tank
    fmt.Println("Value of the tank interface is: ", t)
    fmt.Printf("Type of the tank interface is: %T ", t)
}

输出:

Value of the tank interface is:  <nil>
Type of the tank interface is: <nil> 

在这里,在上面的例子中,我们有一个名为坦克的接口。在这个例子中。
fmt.Println(“坦克接口的值是:”,t)语句返回接口的动态值,fmt.Printf(“坦克接口的类型是:%T”,t)语句返回动态类型,即nil,因为这里接口不知道谁在实现它。

  • 类型断言:在Go语言中,类型断言是一种应用于接口值的操作。或者换句话说,类型断言是一个提取接口值的过程。

语法:

a.(T)

这里,a是接口的值或表达式,T是类型,也被称为断言类型。类型断言用于检查其操作数的动态类型是否与断言的类型相符。如果T是具体的类型,那么类型断言检查a的动态类型是否等于T,如果检查成功,那么类型断言返回a的动态值。如果T是一个接口类型,那么类型断言检查a的给定动态类型是否满足T,这里如果检查成功,那么动态值不会被提取。

示例:

// Go program to illustrate
// the type assertion
package main
  
import "fmt"
  
func myfun(a interface{}) {
  
    // Extracting the value of a
    val := a.(string)
    fmt.Println("Value: ", val)
}
func main() {
  
    var val interface {
    } = "GeeksforGeeks"
      
    myfun(val)
}

输出:

Value:  GeeksforGeeks

在上面的例子中,如果我们把这个val := a.(string)语句改为val := a.(int),那么程序就会恐慌。所以为了克服这个问题,我们使用以下语法。

value, ok := a.(T)

在这里,如果a的类型等于T,那么value就包含了a的动态值,ok将被设置为true。而如果a的类型不等于T,则ok设置为false,value包含零值,程序也不会慌乱。如下面的程序所示。

示例:

// Go program to illustrate type assertion
package main
  
import "fmt"
  
func myfun(a interface{}) {
    value, ok := a.(float64)
    fmt.Println(value, ok)
}
func main() {
  
    var a1 interface {
    } = 98.09
  
    myfun(a1)
  
    var a2 interface {
    } = "GeeksforGeeks"
  
    myfun(a2)
}

输出:

98.09 true
0 false
  • 类型转换:在Go接口中,类型转换用于比较接口的具体类型和case语句中提供的多种类型。它类似于类型断言,只有一个区别,即case指定的是类型,而不是值。你也可以将一个类型与接口类型进行比较。如下面的例子所示。

示例:

// Go program to illustrate type switch
package main
  
import "fmt"
  
func myfun(a interface{}) {
  
    // Using type switch
    switch a.(type) {
  
    case int:
        fmt.Println("Type: int, Value:", a.(int))
    case string:
        fmt.Println("\nType: string, Value: ", a.(string))
    case float64:
        fmt.Println("\nType: float64, Value: ", a.(float64))
    default:
        fmt.Println("\nType not found")
    }
}
  
// Main method
func main() {
  
    myfun("GeeksforGeeks")
    myfun(67.9)
    myfun(true)
}

输出:

Type: string, Value:  GeeksforGeeks

Type: float64, Value:  67.9

Type not found
  • 接口的使用:你可以在方法或函数中使用接口,你想在其中传递不同类型的参数,就像Println()函数。或者你也可以在多种类型实现同一接口时使用接口。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程