5
package main

import (
    "fmt"
)

type bar struct {
}

func (b bar) String() string {
    return "bar"
}

type foo struct {
    b []*bar
    bb *bar
}

func main() {
    f := foo{b: []*bar{&bar{}}, bb:&bar{}}
    fmt.Println(f, f.b, f.bb)
}

Why the result is

{[0x176f44] 0x176f44} [bar] bar

Not

{[bar] bar} [bar] bar

Are there any reasons behind it? It seems easy to implement and good for readability.

Helin Wang
  • 3,780
  • 1
  • 27
  • 31

1 Answers1

4

You have several problems in your code. You define Stirng on bar which is unexported, your fields are unexported as well. This works:

type Bar struct {
}

func (b Bar) String() string {
    return "bar"
}

type foo struct {
    B  []Bar
    BB Bar
}

func main() {
    f := foo{B: []Bar{Bar{}}, BB: Bar{}}
    fmt.Println(f)
}

Playground: https://play.golang.org/p/OhoIcB7cA3.

This would also work with *Bar.

Ainar-G
  • 31,424
  • 10
  • 89
  • 112
  • 1
    Thank you! Can you explain why they must be exported? If it prints out something, fmt.Println is already using reflection to inspect the unexported fields, so why it don't just print out the String() version? json.Marshal is similar, but un-exported field will not be serialized. – Helin Wang Mar 15 '17 at 18:04
  • 1
    @HelinWang If it prints `{}`, then it doesn't access the unexported fields, it just knows that it's a struct. In fact, I don't think you can access unexported fields with `reflect`. That is the reason packages that work with your data, like `fmt` and `encoding/json` need exported fields. – Ainar-G Mar 15 '17 at 19:56
  • 1
    It prints `{[0x176f44] 0x176f44}`. I think reflect can access unexported field: http://stackoverflow.com/questions/17981651/in-go-is-there-any-way-to-access-private-fields-of-a-struct-from-another-packag – Helin Wang Mar 16 '17 at 21:21
  • I guess I was wrong about reading unexported fields. So I don't really know why it doesn't use `String()`. – Ainar-G Mar 17 '17 at 07:27