Skip to content

类型断言与类型分发 ​

难度:⭐ 基础 ​

考点 ​

  • type switch 语法
  • 接口的动态类型判断
  • 多态与类型筛选

题目描述 ​

实现图形接口 Shape,包括 Circle、Rectangle、Triangle 的面积和周长方法, 以及基于 type switch 的 Describe、FilterByType 函数。

提示 ​

  1. 圆面积 πr²,周长 2πr
  2. 海伦公式:s=(a+b+c)/2, Area=√(s(s-a)(s-b)(s-c))
  3. type switch: switch v := s.(type) { case Circle: ... }

参考答案(Go) ​

点击展开参考答案
go
//go:build ignore

package answer

import (
	"fmt"
	"math"
)

type Shape interface {
	Area() float64
	Perimeter() float64
}

type Circle struct{ Radius float64 }
type Rectangle struct{ Width, Height float64 }
type Triangle struct{ A, B, C float64 }

func (c Circle) Area() float64      { return math.Pi * c.Radius * c.Radius }
func (c Circle) Perimeter() float64  { return 2 * math.Pi * c.Radius }
func (r Rectangle) Area() float64    { return r.Width * r.Height }
func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) }
func (t Triangle) Area() float64 {
	s := (t.A + t.B + t.C) / 2
	return math.Sqrt(s * (s - t.A) * (s - t.B) * (s - t.C))
}
func (t Triangle) Perimeter() float64 { return t.A + t.B + t.C }

func Describe(s Shape) string {
	switch v := s.(type) {
	case Circle:
		return fmt.Sprintf("Circle with radius %g", v.Radius)
	case Rectangle:
		return fmt.Sprintf("Rectangle %gx%g", v.Width, v.Height)
	case Triangle:
		return fmt.Sprintf("Triangle with sides %g, %g, %g", v.A, v.B, v.C)
	default:
		return "Unknown shape"
	}
}

func TotalArea(shapes []Shape) float64 {
	var total float64
	for _, s := range shapes {
		total += s.Area()
	}
	return total
}

func FilterByType(shapes []Shape, typeName string) []Shape {
	var result []Shape
	for _, s := range shapes {
		switch typeName {
		case "circle":
			if _, ok := s.(Circle); ok { result = append(result, s) }
		case "rectangle":
			if _, ok := s.(Rectangle); ok { result = append(result, s) }
		case "triangle":
			if _, ok := s.(Triangle); ok { result = append(result, s) }
		}
	}
	return result
}

持续学习,持续构建。