代码之家  ›  专栏  ›  技术社区  ›  InFamous X

指向接口的指针不是接口错误?

  •  0
  • InFamous X  · 技术社区  · 6 年前

    以下代码有效:

    type Brace interface {}
    
    type Round struct {
        prev_ Brace
    }
    
    type Square struct {}
    
    func main() {
        var r Round
        var s Square
        r.prev_ = s
    }
    

    是真的吗 r.prev_ 现在是 s ? 我怎样才能改变它,那一轮将包含一个指向大括号的指针?此代码不起作用:

    type Brace interface {}
    
    type Round struct {
        prev_ *Brace
    }
    
    type Square struct {}
    
    func main() {
        var r Round
        var s Square
        r.prev_ = &s
    }
    

    因为这个错误:

    不能在赋值中使用&s(type*Square)作为type*大括号: *大括号是指向接口的指针,而不是指向接口

    1 回复  |  直到 6 年前
        1
  •  8
  •   Himanshu    6 年前

    正如错误所说:

    不能将&s(类型*正方形)用作赋值中的类型*大括号:*大括号是 指向接口而不是接口的指针

    接口可以包装任何类型的值。但您是在指针类型接口而不是接口中包装结构。这不是高朗界面的工作原理。

    如果要传递结构的地址。接口可以直接包装指向结构的指针。不需要创建指向接口的指针来实现这一点。

    type Brace interface {}
    
    type Round struct {
        prev_ Brace
    }
    
    type Square struct {}
    
    func main() {
        var r Round
        var s Square
        r.prev_ = &s
        fmt.Printf("%#v", r)
    }
    

    Playground Example

    在Golang中,应避免将指针传递给接口:

    编译器将抱怨此错误,但这种情况可能 仍然令人困惑,因为有时需要一个指针 满足一个接口。我的理解是,尽管一个指向 具体类型可以满足接口,但有一个例外是指针 一个接口永远不能满足一个接口。

    考虑变量声明,

    var w io.Writer
    

    打印函数fmt.Fprintf将满足io.Writersomething(实现规范写入方法)的值作为其第一个参数。这样我们就可以写作了

    fmt.Fprintf(w, "hello, world\n")
    

    但是,如果我们传递w的地址,程序将不会编译。

    fmt.Fprintf(&w, "hello, world\n") // Compile-time error.
    

    唯一的例外是任何值,甚至是指向接口的指针, 可以分配给空接口类型的变量(接口{})。 即使如此,如果值是指向 一个接口;结果可能会令人困惑。

    检查一下 Go playground . 当试图将指针传递到接口时,您将在代码段中发现与此相同的错误。