# 接口知识点小问题
* * * * *
--: 作者:Mick
时间:2018年10月17日
* * * * *
友情链接:https://www.cnblogs.com/concurrency/p/4311958.html
1:接口的值什么情况下为nil
```
type Pet interface{
Category()
}
type Dog struct{
}
func(d Dog) Category(){
}
func main(){
var d *Dog
var p Pet = d
fmt.Println(p == nil)
}
```
2:接口组合方法是否允许重复
```
type Animal interface{
Category()
}
type Pet interface{
Animal
Category()
}
```
3:判断类型变量是否实现接口
```
value,ok := interface{}(structValue).(interfaceName)
```
4:实现如下接口
```
package main
import "fmt"
//登录
type Loginer interface{
Login(account string,password string)error
}
//注册
type Register interface{
Regist(account string,code int)error
}
//找回密码
type Retriever interface{
Retrieve(account string,code int,password string) error
}
//登录 注册
type LoginRegister interface{
Loginer
Register
}
//登录 注册 找回密码
type LoginRegistRetriever interface{
Loginer
Register
Retriever
}
//接口的嵌套实现
type Collect struct{
account string
password string
}
// 值接收者实现Login方法,类型值与类型指针可调用
func(c Collect) Login(account string,password string)error{
return nil
}
// 指针接收者实现Regist方法, 类型指针可调用
func(c *Collect) Regist(account string,code int)error{
return nil
}
// 指针接收者实现Retrieve方法,类型值与类型指针可调用
func(c *Collect)Retrieve(account string,code int,password string) error{
return nil
}
// 结构体嵌套,只要会说话和跳舞的都是动物
type Animal interface{
Say(name string)
Dance()
}
// 定义一个Dog结构体
type Dog struct{
}
//值接收者Say
func (d Dog) Say(name string){
fmt.Println("Dog Say")
}
func (d Dog) Dance(){
fmt.Println("Dog Dance")
}
// 萨摩结构体 匿名字段实现组合功能
type SaMo struct{
Dog
}
func(s SaMo) Eat(){
fmt.Println("SaMo Eat")
}
// 博美结构体 拥有SaMo与Dog的属性与方法
type MoMei struct{
SaMo
Dog
}
// 哈士奇比较牛逼 想要自己用指针方法接收者实现所有方法
type HaShiQi struct{
}
func(h *HaShiQi) Say(name string){
}
func(h HaShiQi) Dance(){
}
func demo1(){
var l LoginRegistRetriever
c := &Collect{}
l = c // c 是Collect的类型指针 实现了所有方法
fmt.Printf("%T %v",l,l)
}
func demo2(){
var a Animal
samo := SaMo{} // 类型值只包含 值接受者方法
a = samo // SaMo 的嵌套字段Dog的方法实现了接口,根据内部字段上升到外部字段的原理,则表示SaMo拥有Say与Dance这两个方法
fmt.Printf("%T %v",a,a)
}
func demo3(){
var a Animal
h := &HaShiQi{} // 类型的指针只包含 值接受者方法 + 指针接受者方法
a = h
fmt.Printf("%T %v",a,a)
}
func main(){
// 演示了多态的概念,只要结构体的值实现了接口,则可把结构体的值赋值给接口的值
demo1()
// 结构体嵌套实现接口。就是这样莫名其面就实现了
demo2()
//展示指针接收者实现接口的规则 1,2
demo3()
//1:类型值只包含 值接受者方法
//2:类型的指针只包含 值接受者方法 + 指针接受者方法
//3:接口命名以er结尾 最小单元只包含一个方法
//4:使用嵌套实现方法复用
//5:同级嵌套避免方法名称一致
//6:函数签名表示传入与返回参数的类型与顺序一致
//7:多态函数 可接受任意实现接口的类型值
}
```
5:接口内部实现原理简介
```
package main
import "fmt"
type LoginOner interface{
login()
}
type LoginTwoer interface{
login()
}
type Collect struct{}
func(c *Collect)login(){}
func(c *Collect)register(){}
func main(){
var loginOne LoginOner
var loginTwo LoginTwoer
loginOne = &Collect{}
loginTwo = loginOne
fmt.Printf("Type:%T Value:%v\n",loginOne,loginOne)
fmt.Printf("Type:%T Value:%v\n",loginTwo,loginTwo)
u := User{1,"Tom"}
var i interface{} = &u // 接⼝转型返回临时对象,只有使⽤指针才能修改其状态。 i.(User).name 报错
u.id = 100
i.(*User).name = "mick"
fmt.Printf("Type:%T Value:%v\n",u,u)
fmt.Printf("Type:%T Value:%v\n",i,i.(*User))
}
type User struct{
id int
name string
}
接⼝对象由接⼝表 (interface table) 指针和数据指针组成。
struct Iface{
tab *Itab
data *void
}
struct Itab{
inter *InterfaceType
type *Type
(*fun[])(void) void
}
接⼝表存储元数据信息,包括接⼝类型、动态类型,以及实现接⼝的⽅法指针。⽆论是反
射还是通过接⼝调⽤⽅法,都会⽤到这些信息。
数据指针持有的是⺫标对象的只读复制品,复制完整对象或指针
```