原创声明
作者:刘丹冰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之编译器原理