Почему% v выводит неожиданное значение для вложенной структуры? - PullRequest
0 голосов
/ 29 октября 2018

При печати структуры с вложенной структурой, в которой реализован String (), формат %v выводит «неожиданное» значение для нашего понимания.

Ниже приведен фрагмент кода.

package main

import (
  "fmt"
)

type Inner struct {
}

type A struct {
    Inner
    FieldA string
}

func (i Inner) String() string {
    return "anything"
}

func main() {
    myA := A{FieldA: "A"}
    fmt.Printf("%v", myA)
}

Мы ожидаем, что результат будет

{что-нибудь A}

Но фактический результат -

ничего

Почему этот результат? Кажется FieldA игнорируется? Чтобы сделать это еще более запутанным, если у нас есть две вложенные структуры, в которых реализована функция String (), то на выходе ожидается.

package main

import (
  "fmt"
)

type Inner struct {
}

type InnerAgain struct {
}

type A struct {
    Inner
    InnerAgain
    FieldA string
}

func (i Inner) String() string {
    return "anything"
}

func (i InnerAgain) String() string {
    return "nothing"
}

func main() {
    myA := A{FieldA: "A"}
    fmt.Printf("%v", myA)
}

Выход

{что-нибудь, ничего A}

...

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Поскольку пакет fmt устанавливает правила для %v как:

Если формат (который неявно% v для Println и т. Д.) Действителен для строки (% s% q% v% x% X), применяются следующие два правила:

  1. Если операнд реализует интерфейс ошибки, будет вызван метод Error для преобразования объекта в строку, которая затем будет отформатирована в соответствии с требованиями глагола (если есть).

  2. Если операнд реализует метод String () string, этот метод будет вызываться для преобразования объекта в строку, которая затем будет отформатирована в соответствии с требованиями глагола (если есть).

Следовательно, %v фактически использует метод String() для аргументов, которые являются строковыми.

0 голосов
/ 29 октября 2018

Поскольку вы встраиваете Inner, вам присущи все его свойства, включая функцию String (). Так что %v на самом деле звонит Inner.String()

Из документов (https://golang.org/pkg/fmt/):

  1. Если операнд реализует метод String() string, этот метод будет вызываться для преобразования объекта в строку, которая затем будет отформатирован в соответствии с требованиями глагола (если есть).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...