6:接口的功能

接口

1:认识接口

在 Golang 中,接口(Interface)是一种类型,它是由一组方法组成的集合。一个类型只要实现了接口中的所有方法,就可以被视为该接口类型的实例。一个类型可以同时实现多个接口,从而具备多个不同的行为。

接口的定义格式为:

type 接口名 interface {
    方法名1(参数列表1) 返回值列表1
    方法名2(参数列表2) 返回值列表2
    // ...
}

其中,接口名首字母通常是大写的,以表示公开的接口类型。每个方法定义了接口的一部分功能,它们由函数签名组成,包括方法名、输入参数和返回值。实现接口的类型必须提供方法的完整实现。

例如,下面是一个简单的接口定义:

type Animal interface {
    Speak() string
}

这个接口规定了一个 Speak() 方法,返回字符串。实现这个接口的类型必须提供一个 Speak() 方法,它返回一个字符串类型的值。

我自己的代码示例

package retrieve2

import (
   "io/ioutil"
   "net/http"
)

type Retriever struct {
}

func (Retriever) Get(url string) string {

   resp, err := http.Get(url)
   if err != nil {
      panic(err)
   }
   defer resp.Body.Close()
   bytes, _ := ioutil.ReadAll(resp.Body)
   return string(bytes)
}
package main

import (
   "fmt"
   retrieve2 "golang/Inter/retrieve2"
)

func getRrtiver() retriver {
   return retrieve2.Retriever{}
}

type retriver interface {
   Get(string) string
}

func main() {
   var r retriver = getRrtiver()
   fmt.Println(r.Get("https://www.imooc.com"))
}

2:接口的定义

image-20230506141547583

1:

package main

import (
	"fmt"
	"go1.19/retriever/mooc"
)

func download(r Retriever) string {
	return r.Get("htts://www.imooc.com")
}

type Retriever interface {
	Get(string) string
}

func main() {
	var r Retriever
	r = mooc.Retriever{"this is a imooc com "}
	fmt.Println(download(r))
}

2:

package real

import (
	"net/http"
	"net/http/httputil"
	"time"
)

type Retriever struct {
	UseAgent string
	Timeout  time.Duration
}

func (r Retriever) Get(url string) string {
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	result, err := httputil.DumpResponse(resp, true)
	resp.Body.Close()
	if err != nil {
		panic(err)
	}
	return string(result)
}

3:接口值的类型

image-20230507002710174

3/1:接口类型判断

在Go语言中,类型断言是一种将接口类型转换为其他类型的方法。它可以用于检查接口类型是否实现了某个特定的接口,或者将接口类型转换为具体的类型。

Go语言中的类型断言有两种形式:类型断言表达式和类型断言语句。

类型断言表达式的语法如下:

value, ok := interfaceVar.(Type)

其中,interfaceVar是一个接口类型的变量,Type是一个具体的类型。如果interfaceVar实现了Type接口,那么value将会是interfaceVar转换为Type类型后的值,ok将会是true。如果interfaceVar没有实现Type接口,那么value将会是Type类型的零值,ok将会是false

下面是一个示例:

var i interface{} = "hello"

s, ok := i.(string)
if ok {
    fmt.Println(s)
}

在这个示例中,我们将一个字符串类型的值赋给了一个接口类型的变量i。然后,我们使用类型断言表达式将i转换为字符串类型,并将结果赋给s。由于i实现了string类型的接口,所以ok的值为true,我们可以打印出s的值。

类型断言语句的语法如下:

value := interfaceVar.(Type)

其中,interfaceVar是一个接口类型的变量,Type是一个具体的类型。如果interfaceVar实现了Type接口,那么value将会是interfaceVar转换为Type类型后的值。如果interfaceVar没有实现Type接口,那么程序将会抛出一个运行时错误。

下面是一个示例:

var i interface{} = "hello"

s := i.(string)
fmt.Println(s)

在这个示例中,我们将一个字符串类型的值赋给了一个接口类型的变量i。然后,我们使用类型断言语句将i转换为字符串类型,并将结果赋给s。由于i实现了string类型的接口,所以我们可以打印出s的值。

需要注意的是,类型断言只能用于接口类型的变量。如果您尝试将一个非接口类型的变量转换为其他类型,那么程序将会抛出一个编译时错误。

package main

import (
   "fmt"
   "go1.19/retriever/mooc"
   real2 "go1.19/retriever/real2"
   "time"
)

func download(r Retriever) string {
   return r.Get("htts://www.imooc.com")
}
func inspect(r Retriever) {
   fmt.Printf("%T , %v", r, r)
   switch v := r.(type) {
   case mooc.Retriever:
      fmt.Println("contents", v.Contents)
   case *real2.Retriever:
      fmt.Println(v.UseAgent)
   }
}

type Retriever interface {
   Get(string) string
}

func main() {
   var r Retriever
   //这个地方也可以是一个指针
   r = &mooc.Retriever{"this is a imooc com "}
   inspect(r)
   fmt.Println(download(r))
   r = &real2.Retriever{
      UseAgent: "jon",
      Timeout:  time.Second,
   }
   inspect(r)

   // type assetion
   if moocRetriever, ok := r.(mooc.Retriever); ok {
      fmt.Println(moocRetriever)
   } else {
      fmt.Println("not a mook retriever")
   }
}
image-20230507003209544

3/2:空接口

在Go语言中,interface{}类型是一种特殊的类型,它可以表示任何类型的值。这使得interface{}类型非常灵活,可以用于编写通用的代码,但也使得它有些抽象和难以理解。

下面是一个示例,演示如何使用interface{}类型:

package main

import "fmt"

func main() {
    var i interface{}

    i = 42
    fmt.Printf("%T %v\n", i, i)

    i = "hello"
    fmt.Printf("%T %v\n", i, i)

    i = []int{1, 2, 3}
    fmt.Printf("%T %v\n", i, i)
}

在这个示例中,我们首先定义了一个interface{}类型的变量i。然后,我们将不同类型的值分别赋给i,包括整数、字符串和整数切片。最后,我们使用fmt.Printf函数打印出i的类型和值。

需要注意的是,当我们将一个值赋给interface{}类型的变量时,Go语言会将该值的类型信息保存在变量中。当我们从interface{}类型的变量中获取值时,我们需要使用类型断言来将其转换为具体的类型。例如,如果我们想将i转换为整数切片类型,可以使用以下代码:

s := i.([]int)
fmt.Printf("%T %v\n", s, s)

在这个示例中,我们使用类型断言将i转换为整数切片类型,并将结果赋给s。然后,我们使用fmt.Printf函数打印出s的类型和值。

需要注意的是,如果我们使用类型断言将interface{}类型的变量转换为错误的类型,或者该变量不包含任何值,程序将会抛出一个运行时错误。因此,在使用类型断言时,我们需要确保变量中包含了正确的类型信息。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌微阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值