Детали реализации fmt.Println в golang

#go

#Вперед #плавающая точность

Вопрос:

Рассмотрим этот код

 import (
  "fmt"
  "math/big"
)

func main() {
    var b1,b2,b3,bigSum big.Float

    b1.SetFloat64(25.3)
    b2.SetFloat64(76.2)
    b1.SetFloat64(53.1)

    bigSum.Add(amp;b1, amp;b2).Add(amp;b3, amp;bigSum)

    fmt.Println(bigSum)   // {53 0 0 1 false [9317046909104082944] 8}
    fmt.Println(amp;bigSum)  // 129.3
 }
  

У меня есть 2 вопроса

  1. Почему я должен передавать bigSum как ссылку (с помощью amp; ), чтобы получить правильный ответ, иначе мы получим обратно объект?

  2. Как Println работает в Go? Я имею в виду, как он узнает, какой формат он должен применять для разных типов?

Комментарии:

1. повторите 2 — он использует отражение. извлеките reflect пакет.

Ответ №1:

  1. Println определяет, реализует ли значение Stringer интерфейс. Если это произойдет, то он вызовет String() для получения форматированного значения. big.Float реализует это для получателя указателя, поэтому вам нужно передать ссылку. В противном случае Println обнаружит, что это структура, и напечатает все ее поля, используя отражение
  2. Go имеет открытый исходный код. Вы можете убедиться сами https://golang.org/src/fmt/print.go?#L738 В нем используются переключатели типов и отражение.