You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go中接口指针赋值报错原因及正确赋值方法

Go代码编译错误分析与修复方案

错误产生的原因

你这里的问题核心是混淆了接口类型和指向接口的指针类型:

  • 你定义的foo结构体中,bar字段的类型是*intr,也就是「指向intr接口的指针」。
  • 而&bar1的实际类型是*bar,虽然*bar确实实现了intr接口,但Go不会自动把一个实现了接口的具体类型指针,转换为「指向接口的指针」——因为接口本身已经是一个包含类型元信息和值的封装体,绝大多数场景下完全不需要使用接口的指针。

编译器的错误提示已经说得很明确:*intr is pointer to interface, not interface,意思是你把具体类型指针当成了接口指针来用,但这俩不是一回事。

正确的赋值方式

根据你的需求,有两种常见的修复方案:

方案1:直接使用接口类型(推荐,绝大多数场景都用这个)

把foo结构体的bar字段类型从*intr改成intr,这样直接赋值实现了接口的类型值(或指针)即可:

package main
import "fmt"

type intr interface { String() string }
type bar struct{}
func (b *bar) String() string { return "bar" }
// 修改字段类型为intr,而非*intr
type foo struct { bar intr }

func main() {
    bar1 := bar{}
    // 直接把*bar类型的&bar1赋值给intr类型的字段
    foo1 := foo{bar: &bar1}
    fmt.Println(foo1)
}

方案2:必须使用接口指针的场景(极少用到)

如果你确实需要保留*intr类型的字段,那得先把*bar赋值给一个intr类型的变量,再取这个变量的地址:

package main
import "fmt"

type intr interface { String() string }
type bar struct{}
func (b *bar) String() string { return "bar" }
type foo struct { bar *intr }

func main() {
    bar1 := bar{}
    // 先把*bar赋值给intr类型变量
    var i intr = &bar1
    // 再取变量的地址赋值给*intr类型的字段
    foo1 := foo{bar: &i}
    fmt.Println(foo1)
}

一般来说,方案1是Go里的常规写法,除非你有特别的理由需要操作接口的指针,否则优先用方案1。

内容的提问来源于stack exchange,提问作者施虞斌

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:38:11