goの値をgoのコードとして出力したい
例えば xs := []string{"foo", "bar"}
であるようなxsをそのような関数Fに渡したときに、リテラルで作ったものそれ自身を出力してほしい。
F(xs) // []string{"foo", "bar"}
そもそものこの機能がほしい目的
- default値としてbuilderのオプションに渡してtext/templateなどで出力したい。
どれくらいのことを考えなくてはいけないんだろう?
- []byte,string,int,bool,string,rune
- int,int64
- new type
- struct
- nestしたstructの扱い
- slice,map
- sliceのときの個々の要素の型の省略
- pointer, nil
- generics
- (import package?)
- (循環参照)
pointer
意外と難しいかも?式で表せられない。以下とかを定義してimportしてもらう(あるいはhelper関数を返す)
func Ptr[T any](v T) *T {
return &v
}
後は無名関数で頑張る(こちらの場合もimportが必要になるかも?)。
fmt.Println(func(v int) *int { return &v }(10))
slices
sliceになった時点でloopにreflectを使いたくなるし、全部reflect.Valueで扱った方が良いのかも?
あとは、値を出力する関数の他に型を出力する関数も用意してあげると良いのかもしれない。
struct
ネストした構造もサポート。流石に循環するような値は取れなくて良いと思う。
ゼロ値をスキップしたいかどうか。出力しないほうが嬉しそうなきもする。
リテラルという意味では、埋め込みは特別な処理をする必要はないかも?
そういえば、composite literalならpointerにも&
は使えるな。
anonymous struct
こういうやつ。これが欲しくなることはある?ない気がする。
var options struct { Verbose bool }
options.Verbose = true
channel
サポートしなくて良い気がする
function
サポートしたくなることある?..ある。わかり易い例では time.Now()
とか。
引数を持たない呼び出しは良いとして、引数を持つような呼び出しはどう扱うべきなんだろう?
Call(F, 10, 20)
=> main.F(10, 20)
とか?そういう感じで頑張る?
なんかインターフェイスを定義しておいたほうが楽なんだろうか?
(元々このパッケージが欲しくなった理由は[]string
だったのだけれど、どこまで頑張るべきなんだろう?文字列で書ききれるものは文字列で扱っちゃったほうが楽な気がする)