douluhaikao93943 2018-08-28 15:19
浏览 124
已采纳

接口的golang地址和接口的区别

I have found many similar problem, but not what I want please see following codes.

(1)

var buf bytes.Buffer
fmt.Fprint(&buf,"test")

(2)

var w http.ResponseWriter
http.Error(w,http.StatusText(http.StatusBadRequest),http.StatusBadRequest)

both http.ResponseWriter and bytes.Buffer implement io.Writer interface, so I think they should have same behavior.

when I change to

http.Error(&w,http.StatusText(http.StatusBadRequest),http.StatusBadRequest)

jetbrains goland tell me

Cannot use '&w' (type *http.ResponseWriter) as type ResponseWriter

I wonder why buf have '&' can works, but another don't work?

I googled, somebody say when pass value to function, it can reference to &w

but another say if you pass a pointer, it can deference to value

from https://github.com/golang/go/wiki/MethodSets#variables

To make it easier to remember these rules, it may be helpful to simply consider the pointer- and value-receiver methods separately from the method set. It is legal to call a pointer-valued method on anything that is already a pointer or whose address can be taken (as is the case in the above example). It is legal to call a value method on anything which is a value or whose value can be dereferenced (as is the case with any pointer; this case is specified explicitly in the spec).

I am totally confused, I can't understand by myself. I wish you can help me, thank you!

  • 写回答

1条回答 默认 最新

  • dpwbc42604 2018-08-28 21:19
    关注

    Maybe I can try to explain more detailed what all the very good comments are already saying:

    Interfaces are (mostly) pointers in go

    Interfaces in go are implemented (satisfied) if another type implements all the methods an interface defines. Usually that is done by adding the methods on the pointer of the type, not the type directly.

    type SomeInterface interface {
        SomeMethod string
    }
    
    type SomeStruct struct {} // often is a struct but does not have to be
    
    // a method on the structs pointer
    func (s *SomeStruct) SomeMethod string {
        return ""
    }
    

    The results of this:

    1. SomeStruct does NOT implement SomeInterface, *SomeStruct does!
    2. An Interface is (usually) already a pointer.

    Your example

    var b bytes.Buffer
    fmt.Fprintf(&b, "some text")
    
    var w http.ResponseWriter
    http.Error(w, "some error", 1)
    

    Variable b of type bytes.Buffer is a struct as you can see from the source code:

    type Buffer struct {
        buf       []byte   // contents are the bytes buf[off : len(buf)]
        off       int      // read at &buf[off], write at &buf[len(buf)]
        bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
        lastRead  readOp   // last read operation, so that Unread* can work correctly.
    
        // FIXME: it would be advisable to align Buffer to cachelines to avoid false
        // sharing.
    }
    

    If you want to use it as type io.Writer (interface) you need to get a pointer of bytes.Buffer as (usually) pointer methods are used in go: fmt.Fprintf(&b, "some text")

    Variable w of type http.ResponseWriter is an interface:

    type ResponseWriter interface {
        Header() Header
        Write([]byte) (int, error)
        WriteHeader(statusCode int)
    }
    

    Since interfaces are (usually) already pointers to some underlying implementation we can use it without taking a pointer: http.Error(w, "some error", 1).

    Interface initialisation

    An interface itself cannot be initialised and used! You always need a struct or other type to implement the interface and then you can initialise that and use it as type SomeInterface. For example here is the implementation of gin for a http.ResponseWriter. As you can see from the code it uses pointer receivers for its methods. So http.ResponseWriter is already a pointer to a struct.

    Disclaimer

    This is just one way of trying to make this complex topic sound simple (hopefully). This is not a technically complete or completely accurate explanation. Trying to stay simple and yet as accurate as possible.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 怎么判断同步时序逻辑电路和异步时序逻辑电路
  • ¥15 差动电流二次谐波的含量Matlab计算
  • ¥15 Can/caned 总线错误问题,错误显示控制器要发1,结果总线检测到0
  • ¥15 C#如何调用串口数据
  • ¥15 MATLAB与单片机串口通信
  • ¥15 L76k模块的GPS的使用
  • ¥15 请帮我看一看数电项目如何设计
  • ¥23 (标签-bug|关键词-密码错误加密)
  • ¥66 比特币地址如何生成taproot地址
  • ¥20 数学建模数学建模需要