不能将数据(键入接口{})转换为string:需要types断言

我很新的去,我正在玩这个通知包。

起初,我有这样的代码:

func doit(w http.ResponseWriter, r *http.Request) { notify.Post("my_event", "Hello World!") fmt.Fprint(w, "+OK") } 

我想追加换行到Hello World! 但不是在函数doit上面,因为这将是相当微不足道的,但在handler之后如下所示:

 func handler(w http.ResponseWriter, r *http.Request) { myEventChan := make(chan interface{}) notify.Start("my_event", myEventChan) data := <-myEventChan fmt.Fprint(w, data + "\n") } 

go run

 $ go run lp.go # command-line-arguments ./lp.go:15: invalid operation: data + "\n" (mismatched types interface {} and string) 

经过一些Googlesearch后,我发现这个问题 。

然后我更新我的代码:

 func handler(w http.ResponseWriter, r *http.Request) { myEventChan := make(chan interface{}) notify.Start("my_event", myEventChan) data := <-myEventChan s:= data.(string) + "\n" fmt.Fprint(w, s) } 

这是我应该做的吗? 我的编译器错误消失了,所以我猜这是相当不错的? 这是否有效? 你应该做不同的事情吗?

根据Go规范 :

对于接口types和typesT的expression式x,主expression式x。(T)声明x不是零,并且存储在x中的值是typesT.

“types断言”允许你声明一个包含某个具体types的接口值,或者它的具体types满足另一个接口。

在你的例子中,你是断言数据(types接口{})具有具体的typesstring。 如果你错了,程序会在运行时恐慌。 你不需要担心效率,检查只需要比较两个指针值。

如果你不确定它是否是一个string,你可以使用两个返回语法来testing。

 str, ok := data.(string) 

如果数据不是string,ok将是错误的。 那么把这样的陈述包含在if语句中是很常见的,如下所示:

 if str, ok := data.(string); ok { /* act on str */ } else { /* not string */ } 

键入断言

这被称为golang中的type assertion ,这是一种常见的做法。

这里是去旅行的解释:

types断言提供对接口值的基础具体值的访问。

 t := i.(T) 

这个语句声明了接口值 i保存了具体的types T,并将基础的T值赋给了variablest。

如果我不持有T,则会引发恐慌。

为了testing一个接口值是否拥有一个特定的types,一个types断言可以返回两个值:基础值和一个报告断言是否成功的布尔值。

 t, ok := i.(T) 

如果我拥有一个T,那么t就是底层的价值,OK就是真的。

如果不是的话,ok将是false,t将是T型的零值,不会发生恐慌。

注意: i应该是接口types

陷阱

即使i是一个接口types, []i不是接口types。 因此,为了将[]i转换为它的值types,我们必须单独做:

 // var items []i for _, item := range items { value, ok := item.(T) dosomethingWith(value) } 

性能

至于性能,它可能比直接访问实际值要慢,如在这个计算器的答案中所示 。

 //an easy way: str := fmt.Sprint(data)