当前位置: 首页 > 知识库问答 >
问题:

无法将数据(类型接口{})转换为类型字符串:需要类型断言

梁韬
2023-03-14

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

起初,我有这样的代码:

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

我想在 Hello World 后面附加换行符! 但不是在上面的函数 doit 中,因为这将非常简单,但在之后的处理程序中如下所示:

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 lp.go 
# command-line-arguments
./lp.go:15: invalid operation: data + "\n" (mismatched types interface {} and string)

在谷歌搜索了一下之后,我在SO上发现了这个问题。

然后我将代码更新为:

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)
}

这是我应该做的吗?我的编译器错误消失了,所以我想这很好?这样有效率吗?你应该换一种方式吗?

共有3个答案

饶德本
2023-03-14
//an easy way:
str := fmt.Sprint(data)
曹旭东
2023-03-14

这在Go语言中称为类型断言,这是一种常见的做法。

以下是围棋之旅的解释:

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

t := i.(T)

该语句断言接口值i保持具体类型T,并将底层T值赋给变量T。

如果我不持有T,该声明将引发恐慌。

为了测试接口值是否包含特定类型,类型断言可以返回两个值:基础值和报告断言是否成功的布尔值。

t, ok := i.(T)

如果i持有一个T,那么t将是基础值,ok将为真。

如果不是,ok将为假,t将是类型T的零值,并且不会发生恐慌。

注意:值< code>i应该是接口类型。

即使i是接口类型,[]i也不是接口类型。因此,为了将[]i转换为其值类型,我们必须单独进行:

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

至于性能,它可能比直接访问实际值慢,如此stackoverflow答案所示。

何勇
2023-03-14

根据Go规范:

对于接口类型和类型T的表达式x,主表达式x(T)断言x不是零,并且存储在x中的值是类型T。

“类型断言”允许您声明接口值包含某个具体类型,或者其具体类型满足另一个接口。

在您的示例中,您断言数据(类型接口{})具有具体的类型字符串。如果你错了,程序会在运行时死机。您不需要担心效率,检查只需要比较两个指针值。

如果您不确定它是否是字符串,可以使用两个返回语法进行测试

str, ok := data.(string)

如果数据不是字符串,ok将为false。然后,通常将这样的语句包装成if语句,如下所示:

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