// 示例二/*
@Author:shdeng 微信号:wupeiqi666
@Video: https://space.bilibili.com/283478842
*/package main
import (
"fmt""reflect"
)
type Person struct {
name string
age int
}
funcsomething(arg interface{}) {
fmt.Println(arg)
}
funcmain() {
something("shdeng")
something(666)
something(4.15)
something(Person{name: "wupeiqi", age: 18})
}
// 示例三package main
import (
"fmt"
)
type Person struct {
name string
age int
}
type Role struct {
title string
count int
}
funcsomething(arg interface{}) {
// 多个类型转换,将arg接口对象转换为。(断言)switch tp := arg.(type) {
case Person:
fmt.Println(tp.name)
case Role:
fmt.Println(tp.title)
casestring:
fmt.Println(tp)
default:
fmt.Println(tp)
}
}
funcmain() {
something("shdeng")
something(666)
something(4.15)
something(Person{name: "wupeiqi", age: 18})
something(Role{title: "管理员", count: 2})
}
非空接口,规范+约束
用于约束结构体中必须含有某个方法
// 示例一package main
import"fmt"// 定义接口type IBase interface {
f1() int
}
// 定义结构体Persontype Person struct {
name string
}
// 为结构体Person定义方法func(p Person) f1() int {
return123
}
// 定义结构体Usertype User struct {
name string
}
// 为结构体User定义方法func(p User) f1() int {
return666
}
// 基于接口的参数,可以实现传入多中类型(多态),也同时具有约束对象必须实现接口方法的功能funcDoSomething(base IBase) {
result := base.f1() //直接调用 接口.f1() -> 找到其对应的类型并执行其方法
fmt.Println(result)
}
funcmain() {
per := Person{name: "shdeng"}
user := User{name: "wupeiqi"}
DoSomething(per)
DoSomething(user)
}
// 示例二package main
import"fmt"// 定义接口type IBase interface {
f1() int
}
// 定义结构体type Person struct {
name string
}
// 为结构体定义方法func(p *Person) f1() int {
return123
}
// 定义结构体type User struct {
name string
}
// 为结构体定义方法func(p *User) f1() int {
return666
}
// 基于接口的参数,可以实现传入多中类型(多态),也同时具有约束对象必须实现接口方法的功能funcDoSomething(base IBase) {
result := base.f1() // 由于base的约束,此处智能执行IBase中约束的接口。
fmt.Println(result)
}
funcmain() {
per := &Person{name: "shdeng"} // 创建结构体对象并获取其指针对象
user := &User{name: "wupeiqi"}
DoSomething(per)
DoSomething(user)
}
接口底层实现
接口是Go的一种数据类型,接口可以代指任意类型,实现参数、”容器“中可以处理多种数据类型
type eface struct {
_type *_type // 存储类型相关信息
data unsafe.Pointer // 存储数据
}
空接口
现其他对象赋值给空接口, 就是将其他对象相关的值存放到eface的 _type和data
_type是一个结构体内部存储挺多的信息,这里统称为类型相关的信息
// The conv and assert functions below do very similar things.
// The convXXX functions are guaranteed by the compiler to succeed.
// The assertXXX functions may fail (either panicking or returning false,
// depending on whether they are 1-result or 2-result).
// The convXXX functions succeed on a nil input, whereas the assertXXX
// functions fail on a nil input.
func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E))
}
if msanenabled {
msanread(elem, t.size)
}
x := mallocgc(t.size, t, true)
// TODO: We allocate a zeroed object only to overwrite it with actual data.
// Figure out how to avoid zeroing. Also below in convT2Eslice, convT2I, convT2Islice.
typedmemmove(t, x, elem)
e._type = t
e.data = x
return
}
// 示例一package main
funcmain() {
num := 666var object interface{}
// 将num的类型int存储到 _type 中;值8存储到data中
object = num
}
// 示例二package main
funcDoSomething(arg interface{}) {
// 将 num的类型int 存储到 _type 中;值8存储到data中;
}
funcmain() {
num := 666
DoSomething(num)
}
// 示例三package main
type Person struct {
name string
age int
}
funcDoSomething(arg interface{}) {
// 将 info的类型Person 存储到 _type 中;值{name: "shdeng", age: 18}存储到data中;
}
funcmain() {
info := Person{name: "shdeng", age: 18}
DoSomething(info)
}
非空接口
非空接口会定义一些方法来实现约束
type iface struct {
tab *itab // 类型和方法相关
data unsafe.Pointer // 数据
}
type itab struct {
inter *interfacetype // 接口信息,如:接口中定义的方法。
_type *_type // 类型
hash uint32
_ [4]byte
fun [1]uintptr
}
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod // 接口的方法
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2019-07-02 Python进阶(十二)----re模块