原创声明
作者:刘丹冰Aceld, 微信公众号同名

(1) interface的赋值问题

以下代码能编译过去吗?为什么?
package main

import (
    "fmt"
)

type People interface {
    Speak(string) string
}

type Stduent struct{}

func (stu *Stduent) Speak(think string) (talk string) {
    if think == "love" {
        talk = "You are a good boy"
    } else {
        talk = "hi"
    }
    return
}

func main() {
    var peo People = Stduent{}
    think := "love"
    fmt.Println(peo.Speak(think))
}

继承与多态的特点

在golang中对多态的特点体现从语法上并不是很明显。

我们知道发生多态的几个要素:

1、有interface接口,并且有接口定义的方法。

2、有子类去重写interface的接口。

3、有父类指针指向子类的具体对象

那么,满足上述3个条件,就可以产生多态效果,就是,父类指针可以调用子类的具体方法。

var peo People = Stduent{}Student{}People{}Speak(string) string
var peo People = &Student{}

(2) interface的内部构造(非空接口iface情况)

以下代码打印出来什么内容,说出为什么。
package main

import (
    "fmt"
)

type People interface {
    Show()
}

type Student struct{}

func (stu *Student) Show() {

}

func live() People {
    var stu *Student
    return stu
}

func main() {
    if live() == nil {
        fmt.Println("AAAAAAA")
    } else {
        fmt.Println("BBBBBBB")
    }
}

结果

BBBBBBB

分析:

interface

interface在使用的过程中,共有两种表现形式

一种为空接口(empty interface),定义如下:

var MyInterface interface{}

另一种为非空接口(non-empty interface), 定义如下:

type MyInterface interface {
        function()
}
structefaceiface


空接口eface

空接口eface结构,由两个属性构成,一个是类型信息_type,一个是数据信息。其数据结构声明如下:

type eface struct {      //空接口
    _type *_type         //类型信息
    data  unsafe.Pointer //指向数据的指针(go语言中特殊的指针类型unsafe.Pointer类似于c语言中的void*)
}

_type属性:是GO语言中所有类型的公共描述,Go语言几乎所有的数据结构都可以抽象成 _type,是所有类型的公共描述,type负责决定data应该如何解释和操作,type的结构代码如下:

type _type struct {
    size       uintptr  //类型大小
    ptrdata    uintptr  //前缀持有所有指针的内存大小
    hash       uint32   //数据hash值
    tflag      tflag
    align      uint8    //对齐
    fieldalign uint8    //嵌入结构体时的对齐
    kind       uint8    //kind 有些枚举值kind等于0是无效的
    alg        *typeAlg //函数指针数组,类型实现的所有方法
    gcdata    *byte
    str       nameOff
    ptrToThis typeOff
}
unsafe.Pointervoid*


非空接口iface
dataeface
type iface struct {
  tab  *itab
  data unsafe.Pointer
}
itabpair
type itab struct {
  inter  *interfacetype   // 接口自身的元信息
  _type  *_type           // 具体类型的元信息
  link   *itab
  bad    int32
  hash   int32            // _type里也有一个同样的hash,此处多放一个是为了方便运行接口断言
  fun    [1]uintptr       // 函数指针,指向具体类型所实现的方法
}

其中值得注意的字段,个人理解如下:

interface typepackage pathmethodtypehash_type.hashfun

iface
type People interface {
    Show()  
}  

func live() People {
    var stu *Student
    return stu      
}     
return stu匿名变量 People = stulive()People insterface{}iface struct{}ifaceiface struct{}

BBBBBBB
func main() {   
    if live() == nil {  
        fmt.Println("AAAAAAA")      
    } else {
        fmt.Println("BBBBBBB")
    }
}

(3) interface内部构造(空接口eface情况)

下面代码结果为什么?
func Foo(x interface{}) {
    if x == nil {
        fmt.Println("empty interface")
        return
    }
    fmt.Println("non-empty interface")
}
func main() {
    var p *int = nil
    Foo(p)
}

结果

non-empty interface

分析

Foo()x interface{}eface struct{}

Foo(p)x interface{} = p

所以 x 结构体本身不为nil,而是data指针指向的p为nil。


(4) inteface{}与*interface{}

ABCD中哪一行存在错误?
type S struct {
}

func f(x interface{}) {
}

func g(x *interface{}) {
}

func main() {
    s := S{}
    p := &s
    f(s) //A
    g(s) //B
    f(p) //C
    g(p) //D
}

结果

B、D两行错误
B错误为: cannot use s (type S) as type *interface {} in argument to g:
    *interface {} is pointer to interface, not interface
    
D错误为:cannot use p (type *S) as type *interface {} in argument to g:
    *interface {} is pointer to interface, not interface
func f(x interface{})interface{}func g(x *interface{})*interface{}
interface

mail: danbing.at@gmail.com
github: https://github.com/aceld
原创书籍gitbook: http://legacy.gitbook.com/@aceld

创作不易, 共同学习进步, 欢迎关注作者, 回复"zinx"有好礼


文章推荐

开源软件作品

(原创开源)Zinx-基于Golang轻量级服务器并发框架-完整版(附教程视频)

(原创开源)Lars-基于C 负载均衡远程调度系统-完整版

精选文章

典藏版-Golang调度器GMP原理与调度全分析

典藏版-Golang三色标记、混合写屏障GC模式图文全分析

最常用的调试 golang 的 bug 以及性能问题的实践方法?

Golang中的Defer必掌握的7知识点

Golang中的局部变量“何时栈?何时堆?”

使用Golang的interface接口设计原则

流?I/O操作?阻塞?epoll?

深入浅出Golang的协程池设计

Go语言构建微服务一站式解决方案

到此这篇关于“Golang中interface内部构造与面试真题分析”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
浅析Go语言的Interface机制
真的理解go interface了吗?
golang 面试题(十三)interface内部结构和nil详解
Go 语言机制之内存剖析(Language Mechanics On Memory Profiling)
搞定Go单元测试(一)——基础原理
Go接口之nil != nil
VSCode配置golang开发环境
详解Go逃逸分析
Golang设计模式之建造者模式
小米技术出品——走进Golang之编译器原理