面试题答案
一键面试边界情况分析
- 泛型函数调用:
- 类型不匹配:如果在调用
GenericFunc
时传入不同类型的参数,如GenericFunc[CustomType1](CustomType1{1}, CustomType2{1})
,编译器会报错,因为泛型参数T
要求类型一致。 - 自定义类型比较:虽然
CustomType1
和CustomType2
都实现了比较方法,但如果在GenericFunc
中直接使用==
进行比较,对于结构体类型,Go语言默认的==
操作要求结构体的所有字段类型和值都相同。如果结构体包含不可比较的类型(如切片、映射等),直接使用==
会导致编译错误。
- 类型不匹配:如果在调用
- 反射类型比较:
- 反射类型相等判断:使用
reflect.Type
进行类型比较时,CustomType1
和CustomType2
即使结构相同,但由于是不同的自定义类型,reflect.Type
的比较会认为它们是不同的类型。例如,reflect.TypeOf(CustomType1{}) == reflect.TypeOf(CustomType2{})
会返回false
。 - 类型断言问题:在反射中进行类型断言时,如果使用不当,如
v, ok := value.Interface().(CustomType1)
,当value
实际是CustomType2
类型时,ok
会为false
,可能导致运行时错误。
- 反射类型相等判断:使用
Go语言保证正确性和一致性的方式
- 泛型方面:
- 类型约束:Go 1.18的泛型通过类型约束来保证类型的一致性。例如,可以定义一个接口约束,要求传入的类型实现特定的比较方法,然后在泛型函数中使用该约束。例如:
type Comparable interface { Compare(other interface{}) bool } func GenericFunc[T Comparable](a, b T) bool { return a.Compare(b) }
- 编译时检查:泛型的类型检查在编译时进行,确保传入的类型满足泛型函数的要求,避免运行时类型错误。
- 反射方面:
- 严格类型标识:
reflect.Type
提供了严格的类型标识,通过reflect.Type
的比较可以准确判断两个值的类型是否相同。在进行类型断言时,可以结合reflect.Type
的判断来确保类型的正确性。 - 类型断言检查:在反射中进行类型断言时,使用带
ok
的形式(如v, ok := value.Interface().(CustomType1)
),通过检查ok
来判断类型断言是否成功,避免运行时错误。同时,可以结合reflect.Type
的信息来提前判断是否可以进行类型断言。
- 严格类型标识:
通过泛型的编译时类型检查和反射的严格类型标识与类型断言检查,Go语言在泛型和反射场景下保证了类型相同性判断的正确性和一致性。