25. Package dan modul — Solusi PR

Setiap soal punya foldernya sendiri di exercises/25/homework/solutions/. Untuk menjalankannya, masuk ke foldernya:

cd exercises/25/homework/solutions/01-greet-module
go run .

Soal 1 — Package greet

Soal. Selesaikan package greet yang punya Hello dan Bye.

Cara berpikir. Dua fungsi kecil, masing-masing satu baris cetak. Namanya dimulai dengan huruf kapital, karena main berada di package lain.

Solusi yang dikerjakan. greet/greet.go:

package greet

import "fmt"

func Hello(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

func Bye(name string) {
    fmt.Printf("Goodbye, %s.\n", name)
}

main.go:

package main

import "greetmodule/greet"

func main() {
    greet.Hello("Keiko")
    greet.Bye("Keiko")
}

Output:

Hello, Keiko!
Goodbye, Keiko.

Kesalahan umum.

  • Mengganti nama Hello menjadi hello. main.go lalu berhenti dengan undefined: greet.Hello.
  • Menjalankan dari folder yang salah. cd dulu ke folder yang berisi go.mod dan main.go.
  • Menjalankan go run greet/greet.go. Pustaka tidak bisa dijalankan. Go berhenti dengan package command-line-arguments is not a main package.

Soal 2 — Pembantu matematika

Soal. Package dengan Double dan Triple.

Cara berpikir. Bentuknya sama dengan Soal 1, tetapi fungsinya mengembalikan nilai, bukan mencetak. Pemanggil yang mencetak.

Solusi yang dikerjakan. mathhelpers/mathhelpers.go:

package mathhelpers

func Double(x int) int {
    return x * 2
}

func Triple(x int) int {
    return x * 3
}

main.go:

package main

import (
    "fmt"

    mh "mathmodule/mathhelpers"
)

func main() {
    fmt.Println(mh.Double(7))            // 14
    fmt.Println(mh.Triple(7))            // 21
    fmt.Println(mh.Double(mh.Triple(5))) // 30
}

Kesalahan umum.

  • Menaruh fmt.Println di dalam fungsi package. Dengan mengembalikan nilai, pemanggil bisa memutuskan apa yang dilakukan dengannya.

Soal 3 — Penghitung

Soal. Package dengan Increment, Get, dan Reset. Penghitungnya harus bertahan antarpanggilan.

Cara berpikir. Variabel di bagian atas package, di luar fungsi mana pun, hidup selama program berjalan. Ketiga fungsi membaca dan mengubah variabel yang sama. Namanya huruf kecil, jadi package lain hanya bisa mencapainya lewat ketiga fungsi itu.

Solusi yang dikerjakan. counter/counter.go:

package counter

var count = 0

func Increment() {
    count++
}

func Get() int {
    return count
}

func Reset() {
    count = 0
}

main.go:

package main

import (
    "fmt"

    "countermodule/counter"
)

func main() {
    counter.Increment()
    counter.Increment()
    counter.Increment()
    fmt.Println(counter.Get()) // 3

    counter.Reset()
    fmt.Println(counter.Get()) // 0
}

Kesalahan umum.

  • Mendeklarasikan count di dalam Increment. Setiap panggilan membuat yang baru mulai dari 0. Data yang bertahan antarpanggilan harus berada di luar fungsi.
  • Menulis count := 0 di bagian atas file. := hanya bisa dipakai di dalam fungsi, seperti yang ditunjukkan Bab 21.

Tantangan — Alat string

Soal. Package dengan tiga fungsi string.

Cara berpikir. Shout menggabungkan dua string. Echo membuat slice berisi n salinan dan menggabungkannya. ReverseWords memecah dengan strings.Fields, lalu memakai slices.Reverse dari Bab 24.

Solusi yang dikerjakan. stringutils/stringutils.go:

package stringutils

import (
    "slices"
    "strings"
)

func Shout(s string) string {
    return strings.ToUpper(s) + "!"
}

func Echo(s string, n int) string {
    copies := []string{}
    for range n {
        copies = append(copies, s)
    }
    return strings.Join(copies, " ")
}

func ReverseWords(s string) string {
    words := strings.Fields(s)
    slices.Reverse(words)
    return strings.Join(words, " ")
}

main.go:

package main

import (
    "fmt"

    su "stringmodule/stringutils"
)

func main() {
    fmt.Println(su.Shout("hello"))                     // HELLO!
    fmt.Println(su.Echo("hi", 4))                      // hi hi hi hi
    fmt.Println(su.ReverseWords("one two three four")) // four three two one
}

for range n adalah perulangan "lakukan ini n kali" dari Bab 18. Bentuk ini butuh Go 1.22, dan go.mod menyatakannya di baris terakhir.

Kesalahan umum.

  • Memakai strings.Split(s, " ") alih-alih strings.Fields(s). Fields bisa menangani beberapa spasi berturut-turut; Split memberimu string kosong di antaranya.

Selesai?

Bagian 5 selesai begitu keempat program PR berjalan. Mini-proyek Bagian 5, Petualangan Teks, menggabungkan fungsi, slice, map, dan package menjadi dunia game yang kecil.