以下のコードは望ましくないものを生成します
[20010101 20010102]。
String 関数のコメントを外すと、より良い結果が得られます (ただし、私の実装ではありません)。
[{20010101 1.5} {20010102 2.5}]
ただし、その String 関数は呼び出されません。DateValue の Date は匿名であるため、func (Date) String
DateValue で使用されていることがわかります。
だから私の質問は:
1) これは言語の問題ですか、fmt.Println
実装の問題ですか、それとも何か他の問題ですか? 注:次から切り替える場合:
func (*DateValue) String() string
に
func (DateValue) String() string
私の関数は少なくとも呼び出され、パニックが発生します。したがって、メソッドを本当に呼び出したい場合はそれを行うことができますが、DateValue が実際には非常に大きなオブジェクトであり、参照によってのみ渡したいと仮定します。
2)匿名フィールドと、内部でリフレクションを使用する Stringer や json エンコーディングなどの機能を混在させるための適切な戦略は何ですか? たとえば、たまたま匿名フィールドとして使用されている型に String または MarshalJSON メソッドを追加すると、奇妙な動作が発生する可能性があります (全体の一部のみを出力またはエンコードするなど)。
package main
import (
"fmt"
"time"
)
type Date int64
func (d Date) String() string {
t := time.Unix(int64(d),0).UTC()
return fmt.Sprintf("%04d%02d%02d", t.Year(), int(t.Month()), t.Day())
}
type DateValue struct {
Date
Value float64
}
type OrderedValues []DateValue
/*
// ADD THIS BACK and note that this is never called but both pieces of
// DateValue are printed, whereas, without this only the date is printed
func (dv *DateValue) String() string {
panic("Oops")
return fmt.Sprintf("DV(%s,%f)", dv.Date, dv.Value )
}
*/
func main() {
d1, d2 := Date(978307200),Date(978307200+24*60*60)
ov1 := OrderedValues{{ d1, 1.5 }, { d2, 2.5 }}
fmt.Println(ov1)
}