Skip to content

接口机制详解 - Golang基础面试题

Go语言的接口是其最强大的特性之一,采用隐式实现和鸭子类型,为Go带来了极大的灵活性。本章深入解析接口的各种用法和最佳实践。

📋 重点面试题

面试题 1:Go接口的基本概念和隐式实现

难度级别:⭐⭐⭐
考察范围:接口基础/类型系统
技术标签interface 隐式实现 鸭子类型 方法集

问题分析

Go接口的隐式实现是其独特之处,理解这一机制对于掌握Go的类型系统至关重要。

详细解答

1. 接口的基本概念

点击查看完整代码实现
点击查看完整代码实现
go
package main

import "fmt"

// 定义接口
type Writer interface {
    Write([]byte) (int, error)
}

type Reader interface {
    Read([]byte) (int, error)
}

// 组合接口
type ReadWriter interface {
    Reader
    Writer
}

// 结构体隐式实现接口
type File struct {
    name string
    data []byte
}

// 实现Writer接口的方法
func (f *File) Write(data []byte) (int, error) {
    f.data = append(f.data, data...)
    return len(data), nil
}

// 实现Reader接口的方法
func (f *File) Read(data []byte) (int, error) {
    if len(f.data) == 0 {
        return 0, fmt.Errorf("no data to read")
    }
    
    n := copy(data, f.data)
    f.data = f.data[n:]
    return n, nil
}

func demonstrateBasicInterface() {
    file := &File{name: "test.txt"}
    
    // File自动实现了Writer、Reader和ReadWriter接口
    var writer Writer = file
    var reader Reader = file
    var readWriter ReadWriter = file
    
    // 使用接口
    writer.Write([]byte("Hello, World!"))
    
    buffer := make([]byte, 100)
    n, _ := reader.Read(buffer)
    fmt.Printf("读取数据: %s\n", buffer[:n])
    
    // 接口类型断言
    if f, ok := readWriter.(*File); ok {
        fmt.Printf("文件名: %s\n", f.name)
    }
}

:::

2. 鸭子类型的体现

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
// 不同类型实现相同接口
type ByteBuffer struct {
    buffer []byte
}

func (bb *ByteBuffer) Write(data []byte) (int, error) {
    bb.buffer = append(bb.buffer, data...)
    return len(data), nil
}

type NetworkConnection struct {
    address string
}

func (nc *NetworkConnection) Write(data []byte) (int, error) {
    fmt.Printf("发送到 %s: %s\n", nc.address, string(data))
    return len(data), nil
}

func demonstrateDuckTyping() {
    // 不同类型的对象都实现了Writer接口
    writers := []Writer{
        &File{name: "log.txt"},
        &ByteBuffer{},
        &NetworkConnection{address: "192.168.1.1:8080"},
    }
    
    data := []byte("测试数据")
    
    for i, writer := range writers {
        fmt.Printf("Writer %d: ", i+1)
        writer.Write(data)
    }
}

::: :::

3. 方法集和接收器类型

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
type Counter struct {
    count int
}

// 值接收器方法
func (c Counter) Get() int {
    return c.count
}

// 指针接收器方法
func (c *Counter) Increment() {
    c.count++
}

// 接口定义
type Getter interface {
    Get() int
}

type Incrementer interface {
    Increment()
}

type GetterIncrementer interface {
    Getter
    Incrementer
}

func demonstrateMethodSet() {
    counter := Counter{count: 0}
    counterPtr := &counter
    
    // 值类型的方法集
    var getter1 Getter = counter    // ✅ 可以,值类型实现了Get()
    var getter2 Getter = counterPtr // ✅ 可以,指针类型也可以调用值接收器方法
    
    fmt.Printf("getter1.Get(): %d\n", getter1.Get())
    fmt.Printf("getter2.Get(): %d\n", getter2.Get())
    
    // 指针类型的方法集
    // var incrementer1 Incrementer = counter    // ❌ 不可以!值类型无法实现指针接收器方法
    var incrementer2 Incrementer = counterPtr   // ✅ 可以,指针类型实现了Increment()
    
    incrementer2.Increment()
    
    // 复合接口只能由指针类型实现
    // var getInc1 GetterIncrementer = counter    // ❌ 不可以
    var getInc2 GetterIncrementer = counterPtr   // ✅ 可以
    
    fmt.Printf("getInc2.Get(): %d\n", getInc2.Get())
    getInc2.Increment()
    fmt.Printf("After increment: %d\n", getInc2.Get())
}

::: :::

面试题 2:空接口和类型断言

难度级别:⭐⭐⭐⭐
考察范围:类型断言/反射机制
技术标签empty interface type assertion type switch 反射

问题分析

空接口interface{}可以存储任何类型的值,是Go语言动态类型的基础,类型断言是安全访问底层类型的机制。

详细解答

1. 空接口的使用

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
func demonstrateEmptyInterface() {
    // 空接口可以存储任何类型
    var empty interface{}
    
    empty = 42
    fmt.Printf("存储int: %v, 类型: %T\n", empty, empty)
    
    empty = "hello"
    fmt.Printf("存储string: %v, 类型: %T\n", empty, empty)
    
    empty = []int{1, 2, 3}
    fmt.Printf("存储slice: %v, 类型: %T\n", empty, empty)
    
    empty = struct{ Name string }{Name: "Alice"}
    fmt.Printf("存储struct: %v, 类型: %T\n", empty, empty)
    
    // 空接口切片
    values := []interface{}{42, "hello", true, 3.14}
    for i, v := range values {
        fmt.Printf("values[%d]: %v (%T)\n", i, v, v)
    }
}

::: :::

2. 类型断言的各种形式

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
func demonstrateTypeAssertion() {
    var x interface{} = "hello world"
    
    // 1. 基本类型断言(可能panic)
    str := x.(string)
    fmt.Printf("基本断言: %s\n", str)
    
    // 2. 安全类型断言
    if str, ok := x.(string); ok {
        fmt.Printf("安全断言成功: %s\n", str)
    } else {
        fmt.Println("断言失败")
    }
    
    // 3. 断言失败的例子
    if num, ok := x.(int); ok {
        fmt.Printf("数字: %d\n", num)
    } else {
        fmt.Println("不是int类型")
    }
    
    // 4. 断言接口类型
    var writer interface{} = &File{name: "test.txt"}
    if w, ok := writer.(Writer); ok {
        w.Write([]byte("test data"))
        fmt.Println("成功断言为Writer接口")
    }
    
    // 5. 危险操作示例
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("捕获panic: %v\n", r)
        }
    }()
    
    // 这会panic
    // num := x.(int)  // panic: interface conversion: interface {} is string, not int
}

::: :::

3. 类型开关(Type Switch)

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
func processValue(x interface{}) {
    switch v := x.(type) {
    case nil:
        fmt.Println("值为nil")
    case bool:
        if v {
            fmt.Println("布尔值: true")
        } else {
            fmt.Println("布尔值: false")
        }
    case int:
        fmt.Printf("整数: %d\n", v)
    case int8, int16, int32, int64:
        fmt.Printf("其他整数类型: %v (%T)\n", v, v)
    case string:
        fmt.Printf("字符串: %s (长度: %d)\n", v, len(v))
    case []int:
        fmt.Printf("整数切片: %v (长度: %d)\n", v, len(v))
    case map[string]int:
        fmt.Printf("字符串-整数映射: %v (元素个数: %d)\n", v, len(v))
    case Writer:
        fmt.Println("实现了Writer接口")
        v.Write([]byte("test"))
    case func():
        fmt.Println("无参函数")
        v()
    case func(int) int:
        fmt.Printf("一元函数,调用f(5) = %d\n", v(5))
    default:
        fmt.Printf("未知类型: %T, 值: %v\n", v, v)
    }
}

func demonstrateTypeSwitch() {
    values := []interface{}{
        nil,
        true,
        42,
        int64(100),
        "hello",
        []int{1, 2, 3},
        map[string]int{"a": 1, "b": 2},
        &File{name: "test.txt"},
        func() { fmt.Println("hello from function") },
        func(x int) int { return x * x },
        struct{ Name string }{Name: "Alice"},
    }
    
    for i, v := range values {
        fmt.Printf("--- 处理值 %d ---\n", i+1)
        processValue(v)
    }
}

::: :::

4. 接口的内部表示和性能

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
import (
    "fmt"
    "reflect"
    "unsafe"
)

// 接口的内部结构(简化版)
type iface struct {
    tab  *itab        // 类型信息表
    data unsafe.Pointer // 数据指针
}

type eface struct {
    _type *_type       // 类型信息
    data  unsafe.Pointer // 数据指针
}

func demonstrateInterfaceInternals() {
    // 非空接口
    var writer Writer = &File{name: "test.txt"}
    
    // 空接口
    var empty interface{} = 42
    
    // 使用反射查看接口信息
    writerType := reflect.TypeOf(writer)
    writerValue := reflect.ValueOf(writer)
    
    emptyType := reflect.TypeOf(empty)
    emptyValue := reflect.ValueOf(empty)
    
    fmt.Printf("Writer接口 - 类型: %v, 值: %v\n", writerType, writerValue)
    fmt.Printf("Empty接口 - 类型: %v, 值: %v\n", emptyType, emptyValue)
    
    // 接口比较
    var w1 Writer = &File{name: "file1.txt"}
    var w2 Writer = &File{name: "file2.txt"}
    
    fmt.Printf("不同Writer实例相等: %t\n", w1 == w2) // false
    
    var w3 Writer = w1
    fmt.Printf("相同Writer实例相等: %t\n", w1 == w3) // true
}

::: :::

面试题 3:接口的组合和嵌套

难度级别:⭐⭐⭐⭐
考察范围:接口设计/组合模式
技术标签interface embedding 组合接口 接口分离

问题分析

接口组合是Go语言设计中的重要概念,体现了"组合优于继承"的设计理念。

详细解答

1. 接口组合的基本用法

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
// 基础接口
type Reader interface {
    Read([]byte) (int, error)
}

type Writer interface {
    Write([]byte) (int, error)
}

type Closer interface {
    Close() error
}

// 组合接口
type ReadWriter interface {
    Reader
    Writer
}

type ReadCloser interface {
    Reader
    Closer
}

type WriteCloser interface {
    Writer
    Closer
}

type ReadWriteCloser interface {
    Reader
    Writer
    Closer
}

// 标准库风格的接口组合
type StringWriter interface {
    WriteString(s string) (int, error)
}

type StringReader interface {
    ReadString(delim byte) (string, error)
}

::: :::

2. 实现组合接口

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
type Buffer struct {
    data   []byte
    pos    int
    closed bool
}

// 实现Reader接口
func (b *Buffer) Read(p []byte) (int, error) {
    if b.closed {
        return 0, fmt.Errorf("buffer is closed")
    }
    
    if b.pos >= len(b.data) {
        return 0, fmt.Errorf("EOF")
    }
    
    n := copy(p, b.data[b.pos:])
    b.pos += n
    return n, nil
}

// 实现Writer接口
func (b *Buffer) Write(p []byte) (int, error) {
    if b.closed {
        return 0, fmt.Errorf("buffer is closed")
    }
    
    b.data = append(b.data, p...)
    return len(p), nil
}

// 实现Closer接口
func (b *Buffer) Close() error {
    b.closed = true
    return nil
}

// 实现StringWriter接口
func (b *Buffer) WriteString(s string) (int, error) {
    return b.Write([]byte(s))
}

func demonstrateInterfaceComposition() {
    buffer := &Buffer{}
    
    // Buffer实现了所有组合接口
    var reader Reader = buffer
    var writer Writer = buffer
    var closer Closer = buffer
    var readWriter ReadWriter = buffer
    var readCloser ReadCloser = buffer
    var writeCloser WriteCloser = buffer
    var readWriteCloser ReadWriteCloser = buffer
    var stringWriter StringWriter = buffer
    
    // 使用组合接口
    writer.Write([]byte("Hello, "))
    stringWriter.WriteString("World!")
    
    data := make([]byte, 20)
    n, _ := reader.Read(data)
    fmt.Printf("读取数据: %s\n", data[:n])
    
    // 展示接口的灵活性
    processReadWriter(readWriter)
    processReadCloser(readCloser)
    processWriteCloser(writeCloser)
    processReadWriteCloser(readWriteCloser)
    
    closer.Close()
}

func processReadWriter(rw ReadWriter) {
    rw.Write([]byte(" [ReadWriter]"))
    buffer := make([]byte, 50)
    n, _ := rw.Read(buffer)
    fmt.Printf("ReadWriter处理: %s\n", buffer[:n])
}

func processReadCloser(rc ReadCloser) {
    defer rc.Close()
    buffer := make([]byte, 50)
    n, _ := rc.Read(buffer)
    fmt.Printf("ReadCloser处理: %s\n", buffer[:n])
}

func processWriteCloser(wc WriteCloser) {
    defer wc.Close()
    wc.Write([]byte(" [WriteCloser]"))
}

func processReadWriteCloser(rwc ReadWriteCloser) {
    defer rwc.Close()
    rwc.Write([]byte(" [ReadWriteCloser]"))
    buffer := make([]byte, 100)
    n, _ := rwc.Read(buffer)
    fmt.Printf("ReadWriteCloser处理: %s\n", buffer[:n])
}

::: :::

3. 接口分离原则的应用

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
// 遵循接口分离原则 - 小而专一的接口

// 用户服务接口
type UserReader interface {
    GetUser(id int) (*User, error)
}

type UserWriter interface {
    CreateUser(user *User) error
    UpdateUser(user *User) error
}

type UserDeleter interface {
    DeleteUser(id int) error
}

// 组合成更大的接口
type UserService interface {
    UserReader
    UserWriter
    UserDeleter
}

// 只读用户服务
type ReadOnlyUserService interface {
    UserReader
}

// 用户实体
type User struct {
    ID   int
    Name string
    Email string
}

// 内存用户存储实现
type MemoryUserStore struct {
    users  map[int]*User
    nextID int
}

func NewMemoryUserStore() *MemoryUserStore {
    return &MemoryUserStore{
        users:  make(map[int]*User),
        nextID: 1,
    }
}

func (m *MemoryUserStore) GetUser(id int) (*User, error) {
    user, exists := m.users[id]
    if !exists {
        return nil, fmt.Errorf("user %d not found", id)
    }
    return user, nil
}

func (m *MemoryUserStore) CreateUser(user *User) error {
    if user.ID == 0 {
        user.ID = m.nextID
        m.nextID++
    }
    m.users[user.ID] = user
    return nil
}

func (m *MemoryUserStore) UpdateUser(user *User) error {
    if _, exists := m.users[user.ID]; !exists {
        return fmt.Errorf("user %d not found", user.ID)
    }
    m.users[user.ID] = user
    return nil
}

func (m *MemoryUserStore) DeleteUser(id int) error {
    if _, exists := m.users[id]; !exists {
        return fmt.Errorf("user %d not found", id)
    }
    delete(m.users, id)
    return nil
}

func demonstrateInterfaceSegregation() {
    store := NewMemoryUserStore()
    
    // 不同的服务可以使用不同的接口视图
    var fullService UserService = store
    var readOnlyService ReadOnlyUserService = store
    var readerService UserReader = store
    var writerService UserWriter = store
    
    // 创建用户
    user := &User{Name: "Alice", Email: "alice@example.com"}
    fullService.CreateUser(user)
    
    // 只读服务只能读取
    foundUser, _ := readOnlyService.GetUser(user.ID)
    fmt.Printf("找到用户: %+v\n", foundUser)
    
    // 演示接口分离的好处
    processUserReader(readerService, user.ID)
    processUserWriter(writerService, &User{Name: "Bob", Email: "bob@example.com"})
}

func processUserReader(reader UserReader, id int) {
    user, err := reader.GetUser(id)
    if err != nil {
        fmt.Printf("读取用户失败: %v\n", err)
        return
    }
    fmt.Printf("读取用户成功: %s\n", user.Name)
}

func processUserWriter(writer UserWriter, user *User) {
    err := writer.CreateUser(user)
    if err != nil {
        fmt.Printf("创建用户失败: %v\n", err)
        return
    }
    fmt.Printf("创建用户成功: %s\n", user.Name)
}

::: :::

面试题 4:接口的最佳实践和常见陷阱

难度级别:⭐⭐⭐⭐⭐
考察范围:设计模式/最佳实践
技术标签interface design best practices common pitfalls performance

问题分析

接口设计的最佳实践和常见陷阱是高级Go开发者必须掌握的知识,涉及性能、可维护性和设计原则。

详细解答

1. 接口设计最佳实践

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
// ✅ 好的接口设计:小而专一
type Validator interface {
    Validate() error
}

type Serializer interface {
    Serialize() ([]byte, error)
}

type Deserializer interface {
    Deserialize([]byte) error
}

// ✅ 接受接口,返回具体类型
func ProcessData(validator Validator, serializer Serializer) ([]byte, error) {
    if err := validator.Validate(); err != nil {
        return nil, err
    }
    return serializer.Serialize()
}

// ❌ 不好的接口设计:过大的接口
type BadService interface {
    Create(data []byte) error
    Read(id int) ([]byte, error)
    Update(id int, data []byte) error
    Delete(id int) error
    Validate() error
    Serialize() ([]byte, error)
    Deserialize([]byte) error
    Connect() error
    Disconnect() error
    GetStats() map[string]int
}

// ✅ 好的方式:拆分成小接口
type CRUD interface {
    Create(data []byte) error
    Read(id int) ([]byte, error)
    Update(id int, data []byte) error
    Delete(id int) error
}

type Connection interface {
    Connect() error
    Disconnect() error
}

type Statistics interface {
    GetStats() map[string]int
}

::: :::

2. 常见陷阱和解决方案

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
// 陷阱1:nil接口vs nil值
func demonstrateNilInterfaceTrap() {
    var ptr *int = nil
    var iface interface{} = ptr
    
    fmt.Printf("ptr == nil: %t\n", ptr == nil)         // true
    fmt.Printf("iface == nil: %t\n", iface == nil)     // false!
    fmt.Printf("iface的类型: %T\n", iface)               // *int
    
    // 正确的检查方式
    if iface == nil || reflect.ValueOf(iface).IsNil() {
        fmt.Println("接口为nil或包含nil值")
    }
    
    // 安全的nil检查函数
    fmt.Printf("安全检查结果: %t\n", isNilInterface(iface))
}

func isNilInterface(i interface{}) bool {
    if i == nil {
        return true
    }
    
    v := reflect.ValueOf(i)
    switch v.Kind() {
    case reflect.Chan, reflect.Func, reflect.Interface, 
         reflect.Map, reflect.Ptr, reflect.Slice:
        return v.IsNil()
    default:
        return false
    }
}

// 陷阱2:接口比较的问题
func demonstrateInterfaceComparisonTrap() {
    type Person struct {
        Name string
        Age  int
    }
    
    // 可比较的接口
    var i1 interface{} = Person{Name: "Alice", Age: 30}
    var i2 interface{} = Person{Name: "Alice", Age: 30}
    
    fmt.Printf("相同结构体比较: %t\n", i1 == i2) // true
    
    // 不可比较的接口会panic
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("捕获panic: %v\n", r)
        }
    }()
    
    var i3 interface{} = []int{1, 2, 3}
    var i4 interface{} = []int{1, 2, 3}
    
    // 这会panic: panic: runtime error: comparing uncomparable type []int
    // fmt.Printf("切片比较: %t\n", i3 == i4)
    
    // 安全的接口比较
    fmt.Printf("安全比较结果: %t\n", safeInterfaceEqual(i3, i4))
}

func safeInterfaceEqual(a, b interface{}) bool {
    defer func() {
        if recover() != nil {
            // 如果panic,说明类型不可比较
        }
    }()
    
    return reflect.DeepEqual(a, b)
}

// 陷阱3:接口性能问题
func demonstrateInterfacePerformance() {
    const iterations = 1000000
    
    // 直接调用
    counter := &Counter{}
    start := time.Now()
    for i := 0; i < iterations; i++ {
        counter.Increment()
        _ = counter.Get()
    }
    directTime := time.Since(start)
    
    // 接口调用
    var incrementer Incrementer = counter
    var getter Getter = counter
    counter.count = 0 // 重置
    
    start = time.Now()
    for i := 0; i < iterations; i++ {
        incrementer.Increment()
        _ = getter.Get()
    }
    interfaceTime := time.Since(start)
    
    fmt.Printf("直接调用耗时: %v\n", directTime)
    fmt.Printf("接口调用耗时: %v\n", interfaceTime)
    fmt.Printf("性能开销: %.2fx\n", float64(interfaceTime)/float64(directTime))
}

::: :::

3. 高级接口模式

点击查看完整代码实现
点击查看完整代码实现
点击查看完整代码实现
go
// 策略模式
type SortStrategy interface {
    Sort([]int)
}

type BubbleSort struct{}
func (BubbleSort) Sort(data []int) {
    n := len(data)
    for i := 0; i < n-1; i++ {
        for j := 0; j < n-i-1; j++ {
            if data[j] > data[j+1] {
                data[j], data[j+1] = data[j+1], data[j]
            }
        }
    }
}

type QuickSort struct{}
func (QuickSort) Sort(data []int) {
    if len(data) < 2 {
        return
    }
    quickSort(data, 0, len(data)-1)
}

func quickSort(data []int, low, high int) {
    if low < high {
        pi := partition(data, low, high)
        quickSort(data, low, pi-1)
        quickSort(data, pi+1, high)
    }
}

func partition(data []int, low, high int) int {
    pivot := data[high]
    i := low - 1
    
    for j := low; j <= high-1; j++ {
        if data[j] < pivot {
            i++
            data[i], data[j] = data[j], data[i]
        }
    }
    data[i+1], data[high] = data[high], data[i+1]
    return i + 1
}

// 上下文模式
type Sorter struct {
    strategy SortStrategy
}

func NewSorter(strategy SortStrategy) *Sorter {
    return &Sorter{strategy: strategy}
}

func (s *Sorter) SetStrategy(strategy SortStrategy) {
    s.strategy = strategy
}

func (s *Sorter) Sort(data []int) {
    s.strategy.Sort(data)
}

func demonstrateStrategyPattern() {
    data1 := []int{64, 34, 25, 12, 22, 11, 90}
    data2 := append([]int(nil), data1...) // 复制切片
    
    // 使用冒泡排序
    sorter := NewSorter(BubbleSort{})
    sorter.Sort(data1)
    fmt.Printf("冒泡排序结果: %v\n", data1)
    
    // 切换到快速排序
    sorter.SetStrategy(QuickSort{})
    sorter.Sort(data2)
    fmt.Printf("快速排序结果: %v\n", data2)
}

// 适配器模式
type LegacyPrinter struct{}
func (lp *LegacyPrinter) OldPrint(text string) {
    fmt.Printf("[Legacy] %s\n", text)
}

type Printer interface {
    Print(text string)
}

type PrinterAdapter struct {
    legacy *LegacyPrinter
}

func (pa *PrinterAdapter) Print(text string) {
    pa.legacy.OldPrint(text)
}

func demonstrateAdapterPattern() {
    legacy := &LegacyPrinter{}
    adapter := &PrinterAdapter{legacy: legacy}
    
    var printer Printer = adapter
    printer.Print("适配器模式测试")
}

::: :::

🎯 核心知识点总结

接口基础要点

  1. 隐式实现: Go接口无需显式声明实现,只要实现了接口的所有方法即可
  2. 鸭子类型: "走起来像鸭子,叫起来像鸭子,那就是鸭子"
  3. 方法集: 值类型和指针类型的方法集不同,影响接口实现
  4. 接口值: 接口值包含类型信息和数据指针

类型断言要点

  1. 基本断言: x.(T) 可能panic,需要谨慎使用
  2. 安全断言: v, ok := x.(T) 是安全的检查方式
  3. 类型开关: switch x.(type) 是处理多种类型的优雅方式
  4. 空接口: interface{} 可以存储任何类型的值

接口组合要点

  1. 接口嵌套: 接口可以嵌套其他接口,形成组合接口
  2. 接口分离: 遵循接口分离原则,保持接口小而专一
  3. 组合优于继承: Go通过接口组合实现类似继承的效果
  4. 标准库模式: io包是接口设计的经典示例

最佳实践要点

  1. 接受接口,返回具体类型: 这是Go的重要设计原则
  2. 避免过大接口: 大接口难以实现和维护
  3. 性能考虑: 接口调用有一定开销,但通常可以忽略
  4. 常见陷阱: nil接口、接口比较、方法集匹配等问题

🔍 面试准备建议

  1. 理解核心概念: 深入理解隐式实现和鸭子类型
  2. 掌握实战技巧: 熟练使用类型断言和类型开关
  3. 设计原则: 掌握接口设计的最佳实践
  4. 避免陷阱: 了解常见的接口使用陷阱和解决方案

正在精进