MST

星途 面试题库

面试题:Go类型强制转换在接口类型断言及多态实现中的场景

定义一个接口`Shape`,包含方法`Area()`。再定义两个结构体`Circle`和`Rectangle`,它们都实现了`Shape`接口。现在有一个`[]interface{}`类型的切片,其中包含了`Circle`和`Rectangle`类型的实例。请编写代码通过类型强制转换(类型断言)遍历这个切片,并调用每个实例的`Area`方法,同时说明这里类型强制转换的重要性及可能出现的问题。
19.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

以下是Go语言实现代码:

package main

import (
    "fmt"
)

// 定义Shape接口
type Shape interface {
    Area() float64
}

// 定义Circle结构体
type Circle struct {
    Radius float64
}

// Circle实现Shape接口的Area方法
func (c Circle) Area() float64 {
    return 3.14 * c.Radius * c.Radius
}

// 定义Rectangle结构体
type Rectangle struct {
    Width  float64
    Height float64
}

// Rectangle实现Shape接口的Area方法
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func main() {
    // 创建一个[]interface{}类型的切片,包含Circle和Rectangle实例
    shapes := []interface{}{
        Circle{Radius: 5},
        Rectangle{Width: 4, Height: 6},
    }

    // 遍历切片并调用每个实例的Area方法
    for _, shape := range shapes {
        if s, ok := shape.(Shape); ok {
            fmt.Printf("Area: %f\n", s.Area())
        } else {
            fmt.Println("类型断言失败,不是Shape类型")
        }
    }
}

类型强制转换(类型断言)的重要性:

  1. 接口调用: 通过类型断言,我们可以将interface{}类型的值转换为具体的接口类型(这里是Shape接口),从而调用该接口定义的方法。如果不进行类型断言,Go语言无法确定interface{}具体指向的类型,也就无法调用Area方法。
  2. 代码灵活性: 使用interface{}类型可以让我们的代码更加通用,一个切片可以容纳多种不同类型的值,而类型断言则是在需要的时候将其转换为特定类型进行操作。

可能出现的问题:

  1. 类型断言失败: 如果interface{}实际指向的类型不是我们断言的类型,类型断言会失败。例如,如果在shapes切片中混入了一个非Shape接口实现类型的值,像shapes := []interface{}{Circle{Radius: 5}, "not a shape"},在对"not a shape"进行shape.(Shape)断言时就会失败,导致程序逻辑出现错误。在上述代码中,我们通过ok来检查断言是否成功,避免因断言失败而导致程序崩溃。
  2. 运行时开销: 类型断言在运行时进行检查,这会带来一定的性能开销。如果在性能敏感的代码段频繁进行类型断言,可能会影响程序的整体性能。