MST
星途 面试题库

面试题:Go接口动态与静态类型在函数参数传递和多态实现中的应用与区别

编写一个Go程序,定义一个接口`Shape`,包含方法`Area()`。然后定义两个结构体`Circle`和`Rectangle`都实现`Shape`接口。编写一个函数`CalculateTotalArea`,它接受一个`Shape`类型的切片作为参数,并计算所有形状的总面积。分析在这个过程中,动态类型和静态类型是如何参与并影响程序运行的,尤其是在函数参数传递和多态调用`Area()`方法时。
25.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
)

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

// 定义Circle结构体并实现Shape接口
type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return 3.14 * c.Radius * c.Radius
}

// 定义Rectangle结构体并实现Shape接口
type Rectangle struct {
    Width  float64
    Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

// CalculateTotalArea函数计算所有形状的总面积
func CalculateTotalArea(shapes []Shape) float64 {
    totalArea := 0.0
    for _, shape := range shapes {
        totalArea += shape.Area()
    }
    return totalArea
}

可以通过以下方式调用:

func main() {
    circles := []Circle{
        {Radius: 5},
        {Radius: 3},
    }
    rectangles := []Rectangle{
        {Width: 4, Height: 6},
        {Width: 2, Height: 8},
    }

    var shapes []Shape
    for _, c := range circles {
        shapes = append(shapes, c)
    }
    for _, r := range rectangles {
        shapes = append(shapes, r)
    }

    totalArea := CalculateTotalArea(shapes)
    fmt.Printf("Total Area: %.2f\n", totalArea)
}

动态类型和静态类型分析

  1. 静态类型
    • 在Go语言中,接口类型Shape是静态类型。CalculateTotalArea函数的参数shapes[]Shape类型,这里Shape就是静态类型。
    • 声明变量时,如var shapes []Shapeshapes的静态类型是[]Shape。静态类型在编译时就确定了,它决定了变量可以调用哪些方法。在这个例子中,由于shapes的静态类型是[]Shape,所以可以调用Shape接口定义的Area()方法。
  2. 动态类型
    • 当将CircleRectangle结构体实例添加到shapes切片中时,这些实例的实际类型就是动态类型。例如,circles中的Circle实例和rectangles中的Rectangle实例,在作为Shape类型的元素放入shapes切片后,它们各自的CircleRectangle类型就是动态类型。
    • CalculateTotalArea函数中,通过shape.Area()调用方法时,Go语言会根据shape的动态类型来决定实际调用哪个类型的Area方法。如果shape的动态类型是Circle,就调用CircleArea方法;如果是Rectangle,就调用RectangleArea方法。这就是Go语言实现多态的方式,通过接口的动态类型在运行时确定实际调用的方法。