MST

星途 面试题库

面试题:Go语言空接口在复杂泛型场景中的类型断言处理

给定一个函数,它接受一个空接口类型的参数。这个参数实际传入时可能是一个结构体切片,结构体有多种类型,且每个结构体都有一个名为GetValue的方法返回一个数值(int 或 float64)。请编写该函数实现计算所有结构体GetValue方法返回值的平均值。
42.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
	"fmt"
	"reflect"
)

func calculateAverage(data interface{}) (float64, error) {
	value := reflect.ValueOf(data)
	if value.Kind() != reflect.Slice {
		return 0, fmt.Errorf("expect a slice, got %v", value.Kind())
	}

	var sum float64
	count := 0

	for i := 0; i < value.Len(); i++ {
		element := value.Index(i)
		if element.Kind() != reflect.Struct {
			return 0, fmt.Errorf("element at index %d is not a struct", i)
		}

		method := element.MethodByName("GetValue")
		if !method.IsValid() {
			return 0, fmt.Errorf("struct at index %d does not have GetValue method", i)
		}

		result := method.Call(nil)
		if len(result) != 1 {
			return 0, fmt.Errorf("GetValue method at index %d did not return a single value", i)
		}

		switch result[0].Kind() {
		case reflect.Int:
			sum += float64(result[0].Int())
		case reflect.Float64:
			sum += result[0].Float()
		default:
			return 0, fmt.Errorf("GetValue method at index %d returned an unexpected type %v", i, result[0].Kind())
		}
		count++
	}

	if count == 0 {
		return 0, fmt.Errorf("no valid values to calculate average")
	}

	return sum / float64(count), nil
}

你可以这样调用这个函数:

type Struct1 struct{}
func (s Struct1) GetValue() int {
	return 10
}

type Struct2 struct{}
func (s Struct2) GetValue() float64 {
	return 20.5
}

func main() {
	var data []interface{}
	data = append(data, Struct1{})
	data = append(data, Struct2{})

	avg, err := calculateAverage(data)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Average:", avg)
	}
}

在上述代码中:

  1. calculateAverage 函数接受一个空接口类型的参数。
  2. 首先检查传入的参数是否为切片,如果不是则返回错误。
  3. 然后遍历切片,检查每个元素是否为结构体,并且结构体是否具有 GetValue 方法。
  4. 调用 GetValue 方法获取返回值,并根据返回值的类型进行累加。
  5. 最后计算并返回平均值,如果没有有效数据则返回错误。

main 函数中,定义了两个不同的结构体并实现了 GetValue 方法,将它们组成切片传入 calculateAverage 函数进行测试。