MST

星途 面试题库

面试题:Go类型赋值边界控制的泛化与反射应用

假设在Go项目中,存在多种不同类型(如 `type Age int`、`type Weight float32` 等),每种类型都有各自的赋值边界。现在需要编写一个通用的函数,利用反射机制,能够对任意类型的值进行赋值,并进行对应的边界控制。请详细说明实现思路,并给出完整的代码示例,包括必要的测试代码。
28.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 参数处理:函数接收一个指向变量的指针,这样才能在函数内部修改外部变量的值。
  2. 反射获取信息:使用Go的反射包reflect获取传入值的类型和可设置性,并进行边界检查。
  3. 边界控制:不同类型有不同的边界,例如Age类型可能不能为负数,Weight类型可能有最大最小值等,在设置值之前需要根据类型进行判断。
  4. 值的设置:使用反射的Set方法对变量进行赋值。

代码示例

package main

import (
    "fmt"
    "reflect"
)

// SetValueWithBoundary 通用函数,设置值并进行边界控制
func SetValueWithBoundary(target interface{}, value interface{}) error {
    targetValue := reflect.ValueOf(target)
    if targetValue.Kind() != reflect.Ptr {
        return fmt.Errorf("target must be a pointer")
    }
    targetElem := targetValue.Elem()
    if!targetElem.CanSet() {
        return fmt.Errorf("target is not settable")
    }

    valueType := reflect.TypeOf(value)
    if targetElem.Type() != valueType {
        return fmt.Errorf("value type does not match target type")
    }

    switch valueType.Kind() {
    case reflect.Int:
        v := value.(int)
        if targetElem.Type().String() == "Age" && v < 0 {
            return fmt.Errorf("Age cannot be negative")
        }
        targetElem.SetInt(int64(v))
    case reflect.Float32:
        v := value.(float32)
        if targetElem.Type().String() == "Weight" && (v < 0 || v > 1000) {
            return fmt.Errorf("Weight should be between 0 and 1000")
        }
        targetElem.SetFloat(float64(v))
    default:
        return fmt.Errorf("unsupported type")
    }

    return nil
}

// Age 自定义类型
type Age int
// Weight 自定义类型
type Weight float32

测试代码

package main

import (
    "fmt"
    "testing"
)

func TestSetValueWithBoundary(t *testing.T) {
    var a Age
    err := SetValueWithBoundary(&a, 30)
    if err != nil {
        t.Errorf("Failed to set Age: %v", err)
    }
    if a != 30 {
        t.Errorf("Expected Age to be 30, got %d", a)
    }

    var w Weight
    err = SetValueWithBoundary(&w, 50.5)
    if err != nil {
        t.Errorf("Failed to set Weight: %v", err)
    }
    if w != 50.5 {
        t.Errorf("Expected Weight to be 50.5, got %f", w)
    }

    err = SetValueWithBoundary(&a, -1)
    if err == nil {
        t.Errorf("Expected an error for negative Age, but got nil")
    }

    err = SetValueWithBoundary(&w, 1001)
    if err == nil {
        t.Errorf("Expected an error for Weight out of range, but got nil")
    }
}