FAQ
For custom types who's goal is to satisfy an interface, in the constructor
(or anything which returns a variable of the type), is it better to return
the interface, or the direct type?

For example:

package main

import (
  "fmt"
  "io"
)

type myReader []byte

func (mr *myReader) Read(p []byte) (int, error) {
  return copy(p, *mr), nil
}

func NewMyReader(str string) *myReader {
  var mr myReader = []byte(str)
  return &mr
}

func main() {
  var mr io.Reader
  mr = NewMyReader("foo")

  buf := make([]byte, 128)
  n, err := mr.Read(buf)
  fmt.Printf("msg=%s n=%d err=%v\n", buf, n, err)
}

Should `NewMyReader` be as it is (returns `*myReader`), or should it return
an `io.Reader`? And what would the reason be?
I would think returning the specific type is best as if the type provides
additional methods on top of what the interface provides, it avoids having
the caller do a type assertion to get to it.

I thought I recall seeing an official opinion on this subject, but can't
seem to find anything now.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Kostarev Ilya at Apr 13, 2015 at 5:42 pm
    To my mind
      NewMyReader(str string) myReader
     should better produce myReader explicitly  and
      NewMyRawType(str strings) MyRawType
     should construct MyRawType which implements both myReader and io.Reader and can be used in either circumstances.

    --
    Kostarev Ilya

    On 13 Apr 2015 at 19:58:15, patrick@cloud.com (patrick@cloud.com) wrote:

    For custom types who's goal is to satisfy an interface, in the constructor (or anything which returns a variable of the type), is it better to return the interface, or the direct type?

    For example:

    package main

    import (
     "fmt"
     "io"
    )

    type myReader []byte

    func (mr *myReader) Read(p []byte) (int, error) {
     return copy(p, *mr), nil
    }

    func NewMyReader(str string) *myReader {
     var mr myReader = []byte(str)
     return &mr
    }

    func main() {
     var mr io.Reader
     mr = NewMyReader("foo")

     buf := make([]byte, 128)
     n, err := mr.Read(buf)
     fmt.Printf("msg=%s n=%d err=%v\n", buf, n, err)
    }

    Should `NewMyReader` be as it is (returns `*myReader`), or should it return an `io.Reader`? And what would the reason be?
    I would think returning the specific type is best as if the type provides additional methods on top of what the interface provides, it avoids having the caller do a type assertion to get to it.

    I thought I recall seeing an official opinion on this subject, but can't seem to find anything now.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Paraiso Marc at Apr 13, 2015 at 6:34 pm
    Return *myReader . NewMyReader doesn't have to care that it is an io.Reader
    , only functions taking io.Reader as parameter do. Return a concrete
    type,not an interface.. Anything that takes an io.Reader will accept
    myReader

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gima at Apr 13, 2015 at 6:40 pm
    If your implementation offers some functionality that you want to
    export, then by all means return that implementation or a pointer to
    that. On the other hand if the point of your function's return value is
    to conform to an interface, then just return the interface.

    Remember that no matter which choice you use , it can aid a reader by
    being self-documenting, i.e. function returning an interface makes it
    explicitly clear that the return value conforms to that interface, but
    if your function returns a type conforming to that interface, it's not
    so clear anymore as interfaces are implicitly satisfied in golang.

    Please also notice that, while you can, you probably shouldn't return an
    unexported type from your package. While it can be blindly used by the
    caller of the function, it smells bad :P

    See: https://github.com/golang/go/wiki/CodeReviewComments#receiver-type
    for maybe-useful comments.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedApr 13, '15 at 4:58p
activeApr 13, '15 at 6:40p
posts4
users4
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase