Как разыменовать поля при печати?

http://play.golang.org/p/joEmjQdMaS

package main

import "fmt"

type SomeStruct struct {
    somePointer *somePointer
}
type somePointer struct {
    field string
}

func main() {
    fmt.Println(SomeStruct{&somePointer{"I want to see what is in here"}})
}

Это печатает адрес памяти, подобный этому {0x10500168}

Есть ли способ сделать печать:

{{"I want to see what is in here"}}

Это в основном для целей отладки, если у меня была структура с 30 полями указателей, я не хотел бы делать println для каждого из 30 полей, чтобы увидеть, что в нем.

Ответ 1

Существует большой пакет под названием go-spew. Что именно вы хотите.

package main

import (
  "github.com/davecgh/go-spew/spew"
)

type (
  SomeStruct struct {
    Field1 string
    Field2 int
    Field3 *somePointer
  }
  somePointer struct {
    field string
  }
)

func main() {
  s := SomeStruct{
    Field1: "Yahoo",
    Field2: 500,
    Field3: &somePointer{"I want to see what is in here"},
  }
  spew.Dump(s)

}

Вы получите этот результат:

(main.SomeStruct) {
 Field1: (string) "Yahoo",
 Field2: (int) 500,
 Field3: (*main.somePointer)(0x2102a7230)({
  field: (string) "I want to see what is in here"
 })
}

Ответ 2

package main

import (
    "fmt"
)


type SomeTest struct {
    someVal string
}

func (this *SomeTest) String() string {
    return this.someVal
}

func main() {
    fmt.Println(&SomeTest{"You can see this now"})
}

Все, что предоставляет Stringer интерфейс, будет напечатано с помощью метода String(). Чтобы реализовать стрингер, вам нужно только реализовать String() string. Чтобы сделать то, что вы хотите, вам нужно реализовать Stringer для SomeStruct (в вашем случае, разыменовать somePointer и сделать что-то с этим).

Ответ 3

Вы пытаетесь напечатать структуру, содержащую указатель. Когда вы печатаете структуру, она собирается распечатать значения типов, содержащихся - в этом случае значение указателя указателя строки.

Вы не можете разыменовать строковый указатель внутри структуры, потому что тогда он более точно не описывается структурой, и вы не можете разыменовать структуру, потому что это не указатель.

Что вы можете сделать, это разыменовать указатель строки, но не внутри структуры.

func main() {
    pointer := SomeStruct{&somePointer{"I want to see what is in here"}}.somePointer
    fmt.Println(*pointer)
}

вывод: {I want to see what is in here}

Вы также можете просто напечатать определенное значение из Println:

func main() {
    fmt.Println(SomeStruct{&somePointer{"I want to see what is in here"}}.somePointer)
}

вывод: &{I want to see what is in here}

Еще одна вещь, которую нужно попробовать - Printf:

func main() {
    structInstance := SomeStruct{&somePointer{"I want to see what is in here"}}
    fmt.Printf("%s",structInstance)
}

вывод: {%!s(*main.somePointer=&{I want to see what is in here})}