接口中传值还是引用?
在GoLang语言中,所有的参数传递都是传值,如果定义了一个接口那么接口中是什么呢?
我们可以用一个方法来检测下接口中的东西
定义接口:
type Retriever interface {
Get(s string) string
}
//下载方法
func download(r Retriever) string {
return r.Get("https://www.meituan.com")
}
定义两个个Retriever接口的实现类:
实现类一:
package mock
import "fmt"
type Retriever struct {
Contents string
}
func (r *Retriever) Get(s string) string {
return r.Contents
}
实现类二
package real
import (
"net/http"
"net/http/httputil"
"time"
)
type Retriever struct {
Content string
time.Duration
}
func (r *Retriever) Get(s string) string {
resp, err := http.Get(s)
if err != nil {
panic(err)
}
result, err := httputil.DumpResponse(resp, true)
if err != nil {
panic(err)
}
return string(result)
}
测试方法:
func main() {
var r Retriever
r = &mock.Retriever{Contents: "猪妞妞"}
inspect(r)
r = &real2.Retriever{"lududu", time.Minute,}
}
func inspect(r Retriever) {
fmt.Printf("%T %v\n", r, r)
//fmt.Println(r)
switch v := r.(type) {
case *mock.Retriever:
fmt.Println("Content:", v.Contents)
case *real2.Retriever:
fmt.Println("UserAgent:", v.Content)
}
}
我们可以通过switch来看出接口的类型,从运行结果来看,这个接口类型里面包装的是实现类的类型,和类的值
或者也可以通过typeassertion 的方式来看:
if retriever, ok := r.(mock.Retriever); ok {
fmt.Println(retriever.Contents)
} else {
fmt.Println("类型不对o")
}
在go语言中接口的实现类接收参数可以是指针类型,也可以是值类型,取决于你的业务。
接口的高级用法
可以接收多种类型的参数:
我们知道,静态语言在有编译的阶段,在编译阶段编译器会检查参数的类型等,在Java语言中这种要求更是严格,在go语言中我们可以定义一个方法可以接收各种类型的参数:
只能接收int类型的Queue:
package queueEntry
type Queue []int
func (queue *Queue) Pop() int {
head := (*queue)[0]
*queue = (*queue)[1:]
return head
}
func (queue *Queue) Push(v int) {
*queue = append(*queue, v)
}
func (queue *Queue) IsEmpty() bool {
return len(*queue) == 0
}
可以接收各种类型参数的Queue:
package queueEntry
type Queue []interface{}
func (queue *Queue) Pop() interface{} {
head := (*queue)[0]
*queue = (*queue)[1:]
return head
}
func (queue *Queue) Push(v interface{}) {
*queue = append(*queue, v)
}
func (queue *Queue) IsEmpty() bool {
return len(*queue) == 0
}
如果你的底层slice定义的可以接收任何类型的数据类型,但是你想规定它只能接收int类型的:
package queueEntry
type Queue []interface{}
func (queue *Queue) Pop() int{
head := (*queue)[0]
*queue = (*queue)[1:]
return head.(int)
}
func (queue *Queue) Push(v int) {
*queue = append(*queue, v)
}
func (queue *Queue) IsEmpty() bool {
return len(*queue) == 0
}