# 接口知識點小問題
* * * * *
--: 作者: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
}
接?表存儲元數據信息,包括接?類型、動態類型,以及實現接?的?法指針。?論是反
射還是通過接?調??法,都會?到這些信息。
數據指針持有的是?標對象的只讀復制品,復制完整對象或指針
```