問7 Itemに魂を込めよ
中段 / 目安 30分
「いよいよ本丸、Item 型の移植です」
凛さんの声が少しだけ弾みました。「構造体、税込価格メソッド、売切れ化メソッド、そして不正な商品を生まれさせない NewItem 関数。TypeScript道場の問4、覚えていますか。あれの Go 版です」
構造体は、値をひとまとめにした型です。
Go
type Item struct {
Name string
Price int
Sold bool
}メソッドは、関数名の前にレシーバを付けて書きます。ここで2種類の書き方が出てきます。
Go
func (i Item) TaxIncluded() int { ... } // 値レシーバ
func (i *Item) MarkSold() { ... } // ポインタレシーバ違いは、元の値を変えられるかどうかです。値レシーバは写しを受け取るので、中で書き換えても呼び出し元には反映されません。元を変えたいならポインタレシーバを使います。売切れ化はまさにそれです。
そしてコンストラクタです。Go に特別な構文はありません。ただの関数です。
Go
func NewItem(name string, price int) (*Item, error) {
if name == "" {
return nil, errors.New("商品名は必須です")
}
...
}作れなかったときに error を返すのが要点です。不正な値を持つ Item を、そもそも存在させない。 検証を入口の1か所に集めておけば、その先では中身を疑わずに済みます。型の門番を、Go 側にも立てます。
完成条件
次の3つを作ってください。
Item構造体 —Name(string)Price(int)Sold(bool)TaxIncluded()— 税込価格を返す。消費税は10%で、端数は切り捨てMarkSold()—Soldをtrueにする。元の Item が変わることNewItem(name, price)— 検証つきで(*Item, error)を返す
検証は、名前が空なら 商品名は必須です、価格が 0 以下なら 価格は1円以上です です。
動作を確かめる runItem 関数も書いてください。名前と価格を受け取り、NewItem で作って売切れ化し、結果を返します。作れなかったときは エラー: に続けて理由を返してください。
要件
Item構造体にNamePriceSoldを持たせるTaxIncluded()は税込価格(10%・切り捨て)を返し、MarkSold()は元の Item のSoldをtrueにするNewItemは(*Item, error)を返し、名前が空なら商品名は必須です、価格が 0 以下なら価格は1円以上ですのエラーにする
入出力例
runItem("レザースニーカー", 4800) → "レザースニーカー 税込5280円 sold=true"
runItem("木製のスツール", 3505) → "木製のスツール 税込3855円 sold=true"
runItem("", 4800) → "エラー: 商品名は必須です"
runItem("レザースニーカー", 0) → "エラー: 価格は1円以上です"
runItem("レザースニーカー", -100) → "エラー: 価格は1円以上です"ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです
ヒント 2ヒント 1 を開くと読めます
ヒント 3ヒント 2 を開くと読めます
編集 ゆめさく編集部