面试题答案
一键面试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)
}
}
在上述代码中:
calculateAverage
函数接受一个空接口类型的参数。- 首先检查传入的参数是否为切片,如果不是则返回错误。
- 然后遍历切片,检查每个元素是否为结构体,并且结构体是否具有
GetValue
方法。 - 调用
GetValue
方法获取返回值,并根据返回值的类型进行累加。 - 最后计算并返回平均值,如果没有有效数据则返回错误。
在 main
函数中,定义了两个不同的结构体并实现了 GetValue
方法,将它们组成切片传入 calculateAverage
函数进行测试。