Hello, On Thu, Sep 01, 2016 at 01:59:12AM -0700, Muhammad Shulhan wrote:
> > type Slices []string > > > > func (sl *Slices) String() string { > > return fmt.Sprint(sl) > > } > runtime: goroutine stack exceeds 250000000-byte limit > fatal error: stack overflow It is always dangerous to call fmt.Sprint() (or any other print method of the fmt package) from a String() method of a value that implements the Stringer interface. fmt.Sprint() might call the String() method itselfes, which leads to infinite recursion. >From the fmt documentation (https://golang.org/pkg/fmt/#pkg-overview): | [...] | 5. If an operand implements method String() string, that method will be | invoked to convert the object to a string, which will then be formatted as | required by the verb (if any). Wether this happens or not depends on the concrete execution path of fmt.Sprint(). Even if three of your four exampes work, I guess they could fail with future implementations of the fmt package. You should always pass basic types to fmt.Sprint(), e.g. func (sl *Slices) String() string { return fmt.Sprint([]string(*sl)) } Again, from the fmt documentation: | To avoid recursion in cases such as | | type X string | func (x X) String() string { return Sprintf("<%s>", x) } | | convert the value before recurring: | | func (x X) String() string { return Sprintf("<%s>", string(x)) } | | Infinite recursion can also be triggered by self-referential data | structures, such as a slice that contains itself as an element, if that type | has a String method. Such pathologies are rare, however, and the package | does not protect against them. Harald -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.