面试题答案
一键面试1. 编写通用函数
以下是一个使用 Go 语言实现的示例代码:
package main
import (
"fmt"
)
// 自定义结构体
type MyStruct struct {
Field string
}
// 通用函数
func processValue(v interface{}) {
switch value := v.(type) {
case int:
result := value + 10
fmt.Printf("处理 int 类型: %d + 10 = %d\n", value, result)
case float64:
result := value * 2.5
fmt.Printf("处理 float64 类型: %.2f * 2.5 = %.2f\n", value, result)
case MyStruct:
fmt.Printf("处理自定义结构体: %s\n", value.Field)
default:
fmt.Println("不支持的类型")
}
}
2. 类型断言和类型转换的使用方法
- 类型断言:在 Go 语言中,使用
v := x.(T)
语法进行类型断言,其中x
是接口类型的值,T
是目标类型。如果断言成功,v
就是转换后的T
类型的值;如果断言失败,会触发运行时错误。上述代码中的switch value := v.(type)
语句使用了类型断言,同时获取了断言的值value
以及类型type
。它会根据v
的实际类型,将其转换为相应的类型,并执行对应的分支代码。 - 类型转换:当通过类型断言确认了接口值的实际类型后,就可以直接对其进行相应类型的操作,这其中就隐含了类型转换。例如,在
case int
分支中,value
已经被断言为int
类型,因此可以直接进行int
类型的加法运算。
3. 注意事项
- 运行时错误:如果使用
v := x.(T)
进行类型断言,而x
实际类型并非T
,会触发运行时错误。为了避免这种情况,可以使用v, ok := x.(T)
这种带检测的断言方式,ok
是一个布尔值,表示断言是否成功。例如:
var x interface{} = "hello"
if v, ok := x.(int); ok {
fmt.Println("断言成功:", v)
} else {
fmt.Println("断言失败")
}
- 性能考虑:频繁的类型断言可能会影响性能,特别是在性能敏感的代码中。尽量通过设计良好的接口和多态来避免不必要的类型断言。
- 类型一致性:在进行类型断言和转换时,要确保目标类型与实际类型一致,否则会导致错误的结果或运行时错误。例如,不能将
string
类型的值断言为int
类型并进行数值运算。 - 空接口使用:由于
interface{}
可以存储任意类型的值,在使用类型断言时要全面考虑可能的类型,否则可能会遗漏某些类型的处理,如上述代码中的default
分支就是处理未预料到的类型。