我想要在[]string
中映射一些数据。我可以用两种方式做到:
A)
// someData
s := someData.([]string)
在这种情况下,在控制台上列出错误后执行将停止。
b)中
// someData
s, ok := someData.([]string)
在这种情况下,不会发生错误,但s将具有零值
我想在不停止执行的情况下记录此类断言失败案例中的错误。但是,当我使用类型(b)时,我看不到错误详细信息。
我能想到的唯一解决方案是使用reflect.TypeOf
并打印两种类型。
使用解决方案(b)时,还有其他方法可以解决错误吗?
答案 0 :(得分:15)
您可以自己构建日志消息。由于生成该类型的printf格式字符串reflect
,因此无需显式调用%T
。
s, ok := someData.([]string)
if !ok {
log.Printf("got data of type %T but wanted []string", someData)
... handle the failure somehow
}
在不了解上下文的情况下,我很难生成有用的信息性日志声明,但您可以根据自己的使用情况调整该想法。
答案 1 :(得分:2)
那么,根据你想要做的类型断言的方式,有一种方法可以在a)和b)的情况下得到错误。
所以,我将首先介绍b,因为if是最直接的:你可以使用-->
来获取元素的类型:
%T
另一种方法涉及从错误中恢复,因此您可以将恐慌消息作为错误获取:
func typeAssert(i interface{}) []string {
s, ok := i.([]string)
if !ok {
fmt.Printf("interface conversion: interface is %T, not []string\n", i)
}
return s
}
当然,您可以根据自己的想法添加自己的错误处理方法。第一种解决方案无论如何都允许更大的灵活性,但func assertType(i interface{}) []string {
// Recover
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
return i.([]string)
}
func main() {
assertType([]int{42})
fmt.Println("Recovered from the error")
}
// OUTPUT:
// interface conversion: interface is []int, not []string
// Recovered from the error
有时可能很方便(在这种情况下不一定)。