Goの初心者として、私はio.Writer
を理解するのに問題があります。
私の目標:構造体を取り、それをjsonファイルに書き込みます。
アプローチ:
-encoding/json.Marshal
を使用して構造体をバイトに変換します
-それらのバイトをos.File
ライターにフィードします
これが私がそれを機能させた方法です:
package main
import (
"os"
"encoding/json"
)
type Person struct {
Name string
Age uint
Occupation []string
}
func MakeBytes(p Person) []byte {
b, _ := json.Marshal(p)
return b
}
func main() {
gandalf := Person{
"Gandalf",
56,
[]string{"sourcerer", "foo fighter"},
}
myFile, err := os.Create("output1.json")
if err != nil {
panic(err)
}
myBytes := MakeBytes(gandalf)
myFile.Write(myBytes)
}
この記事 を読んだ後、プログラムを次のように変更しました。
package main
import (
"io"
"os"
"encoding/json"
)
type Person struct {
Name string
Age uint
Occupation []string
}
// Correct name for this function would be simply Write
// but I use WriteToFile for my understanding
func (p *Person) WriteToFile(w io.Writer) {
b, _ := json.Marshal(*p)
w.Write(b)
}
func main() {
gandalf := Person{
"Gandalf",
56,
[]string{"sourcerer", "foo fighter"},
}
myFile, err := os.Create("output2.json")
if err != nil {
panic(err)
}
gandalf.WriteToFile(myFile)
}
私の意見では、最初の例は初心者にとってより簡単で理解しやすいです...しかし、2番目の例は目標を達成するためのGoの慣用的な方法であると感じています。
質問:
1。上記の仮定は正しいですか(2番目のオプションは慣用的になります)?
2。上記のオプションに違いはありますか?どちらのオプションが良いですか?
3。同じ目標を達成する他の方法は?
ありがとうございました、
WM
2番目の方法を使用する利点は、Writer
インターフェイスを渡す場合、Write
を実装するanythingを渡すことができることです。構造体メソッドを変更せずに、ファイルだけでなく、たとえばhttp.ResponseWriter
、またはstdout os.Stdout
。
この便利なブログ投稿はパッケージで見ることができます ioウォークスルー 。作成者は、パラメーターのリーダーおよびライターとして渡すと、コードがより柔軟になると主張しています。これは、非常に多くの関数がReader
およびWriter
インターフェイスを使用しているためです。
Go moreを使用するようになると、標準ライブラリがReader
およびWriter
インターフェイスにどれだけ依存しているかに気付くでしょう。おそらく、それを高く評価するようになります:)
したがって、この関数(名前が変更されました):
// writes json representation of Person to Writer
func (p *Person) WriteJson(w io.Writer) error {
b, err := json.Marshal(*p)
if err != nil {
return err
}
_, err = w.Write(b)
if err != nil {
return err
}
return err
}
File、httpResponse、ユーザーStdout、または単純なバイトバッファ;テストが少し簡単になります。
何をしているのかという理由で名前を変更しました。つまり、この関数はPerson
構造体を取ります。
Writer
に書き込みますもう1つ、Writerはデータ型ではないため(== --- ==)とは何かについて混乱する可能性がありますではなく、interface-これはデータ型の動作であり、型が実装する事前定義されたメソッドです。したがって、Write()
メソッドを実装するものはすべて、ライターと見なされます。
これは初心者にとって最初は理解するのが少し難しいかもしれませんが、インターフェースを理解するのに役立つオンラインのリソースがたくさんあります(そして、ReadWriters
は、Error()
とともに遭遇するより一般的なインターフェースのいくつかです(ei。すべてのエラー))。