diff options
| -rw-r--r-- | CONTRIBUTING.md | 4 | ||||
| -rw-r--r-- | content/concurrency.article | 48 | ||||
| -rw-r--r-- | content/flowcontrol.article | 2 | ||||
| -rw-r--r-- | content/methods.article | 69 | ||||
| -rw-r--r-- | content/moretypes.article | 25 | ||||
| -rw-r--r-- | content/welcome.article | 2 |
6 files changed, 91 insertions, 59 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3746897..9b377e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,10 +38,6 @@ The App Engine version runs code examples against the service at play.golang.org To verify changes to the code examples you must use your local toolchain to compile and run `gotour` locally. -The App Engine version runs code examples against the service at play.golang.org. -To verify changes to the code examples you must use your local toolchain to compile -and run `gotour` locally. - ## Contributing code Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) diff --git a/content/concurrency.article b/content/concurrency.article index 867e682..308342a 100644 --- a/content/concurrency.article +++ b/content/concurrency.article @@ -1,5 +1,5 @@ Konkurensi -Go menyediakan konstruksi konkurensi sebagai bagian dari inti bahasanya. Pelajaran kali ini menjelaskan dan memberikan beberapa contoh penggunaannya. +Go menyediakan konstruksi konkurensi sebagai bagian dari inti bahasanya. Pelajaran kali ini menjelaskan dan memberikan beberapa contoh penggunaannya. Para Penggubah Go https://golang.org @@ -15,7 +15,8 @@ memulai sebuah goroutine baru `f` dengan menjalankan f(x, y, z) -Evaluasi dari nilai `f`, `x`, `y`, dan `z` terjadi di goroutine yang memanggil dan eksekusi dari `f` terjadi di goroutine yang baru. +Evaluasi dari nilai `f`, `x`, `y`, dan `z` terjadi di goroutine yang memanggil +dan eksekusi dari `f` terjadi di goroutine yang baru. Goroutine berjalan di ruang alamat yang sama, sehingga akses ke _shared_memory_ harus disinkronisasi. @@ -29,7 +30,8 @@ membutuhkannya karena ada fungsi primitif lainnya. * Kanal -Kanal adalah sebuah penghubung tipe yang mana anda bisa mengirim dan menerima nilai dengan operator kanal, `<-`. +Kanal adalah sebuah penghubung tipe yang mana anda bisa mengirim dan menerima +nilai dengan operator kanal, `<-`. ch <- v // Kirim v ke kanal ch. v := <-ch // Terima dari ch, dan simpan nilainya ke v. @@ -41,7 +43,8 @@ Seperti map dan slice, kanal harus dibuat sebelum digunakan: ch := make(chan int) Secara bawaan, pengiriman dan penerimaan ditahan sampai sisi yang lain siap. -Hal ini membolehkan goroutine untuk melakukan sinkronisasi tanpa melakukan penguncian secara eksplisit atau menggunakan variabel kondisi. +Hal ini membolehkan goroutine untuk melakukan sinkronisasi tanpa melakukan +penguncian secara eksplisit atau menggunakan variabel kondisi. Contoh kode menjumlahkan angka yang ada di `slice`, dengan mendistribusikan kerja antara dua goroutine. @@ -52,7 +55,8 @@ Saat kedua goroutine selesai, hasil akhirnya kemudian akan dihitung. * Kanal dengan buffer Kanal memiliki _buffer_. -Cukup dengan menambahkan panjang buffer ke argumen kedua pada `make` untuk menginisialisasi buffer kanal: +Cukup dengan menambahkan panjang buffer ke argumen kedua pada `make` untuk +menginisialisasi buffer kanal: ch := make(chan int, 100) @@ -65,14 +69,18 @@ Ubahlah contoh untuk memenuhi buffer dan lihat apa yang terjadi. * "range" dan "close" -Pengirim dapat menutup (`close`) sebuah kanal untuk menandakan bahwa tidak ada lagi data yang dikirim. -Penerima dapat memeriksa apakah kanal telah ditutup dengan menambahkan parameter kedua pada ekspresi penerimaan: +Pengirim dapat menutup (`close`) sebuah kanal untuk menandakan bahwa tidak ada +lagi data yang dikirim. +Penerima dapat memeriksa apakah kanal telah ditutup dengan menambahkan +parameter kedua pada ekspresi penerimaan: v, ok := <-ch -`ok` bernilai `false` jika tidak ada lagi nilai yang diterima dan kanal telah ditutup. +`ok` bernilai `false` jika tidak ada lagi nilai yang diterima dan kanal telah +ditutup. -Pengulangan `for`i`:=`range`c` menerima nilai dari kanal berulang kali sampai ditutup. +Pengulangan `for`i`:=`range`c` menerima nilai dari kanal berulang kali sampai +ditutup. *Catatan:* Hanya pengirim yang menutup kanal, penerima tidak pernah menutupnya. Mengirim ke kanal yang telah tertutup akan menyebabkan kepanikan. @@ -89,7 +97,8 @@ nilai yang akan diterima, misalnya untuk menghentikan pengulangan pada Perintah `select` membuat goroutine menunggu operasi komunikasi. -`select` menahan pembacaan sampai salah satu kondisinya dapat berjalan, kemudian ia mengeksekusi kondisi tersebut. +`select` menahan pembacaan sampai salah satu kondisinya dapat berjalan, +kemudian ia mengeksekusi kondisi tersebut. Ia memilih salah satu kondisi secara acak jika banyak kondisi telah siap. .play concurrency/select.go @@ -118,8 +127,11 @@ Sebagai contohnya, berikut dua binary tree yang menyimpan urutan 1, 1, 2, 3, .image /content/img/tree.png -Sebuah fungsi yang memeriksa apakah dua binary tree menyimpan urutan yang sama, akan cukup kompleks bila diiimplementasikan pada kebanyakan bahasa pemrograman. -Kita akan gunakan konkurensi dan kanal untuk menulis sebuah solusi sederhana menggunakan Go. +Sebuah fungsi yang memeriksa apakah dua binary tree menyimpan urutan yang +sama, akan cukup kompleks bila diiimplementasikan pada kebanyakan bahasa +pemrograman. +Kita akan gunakan konkurensi dan kanal untuk menulis sebuah solusi sederhana +menggunakan Go. Contoh ini menggunakan paket `tree`, yang mendefinisikan tipe: @@ -148,11 +160,13 @@ Buat sebuah kanal baru `ch` dan jalankan fungsi `Walk` Kemudian baca dan cetak 10 nilai dari kanal. Ia harusnya mengeluarkan angka 1, 2, 3, ..., 10. -*3.* Implementasikan fungsi `Same` menggunakan `Walk` untuk menentukan apakah `t1` dan `t2` menyimpan nilai yang sama. +*3.* Implementasikan fungsi `Same` menggunakan `Walk` untuk menentukan apakah +`t1` dan `t2` menyimpan nilai yang sama. *4.* Uji fungsi `Same`. -`Same(tree.New(1),`tree.New(1))` mengembalikan nilai `true`, dan `Same(tree.New(1),`tree.New(2))` mengembalikan nilai `false`. +`Same(tree.New(1),`tree.New(1))` mengembalikan nilai `true`, dan +`Same(tree.New(1),`tree.New(2))` mengembalikan nilai `false`. Dokumentasi untuk `Tree` bisa ditemukan [[https://godoc.org/golang.org/x/tour/tree#Tree][di sini]]. @@ -196,10 +210,8 @@ Ubah fungsi `Crawl` untuk mengambil URL secara paralel tanpa ada duplikasi (mengambil URL yang sama dua kali). _Petunjuk_: anda bisa menyimpan _cache_ dari URL yang telah diambil -menggunakan sebuah map, tapi map tidak aman untuk digunakan secara konkuren! - -_Petunjuk_: anda bisa menyimpan _cache_ dari URL yang telah diambil menggunakan -sebuah `map`, tapi `map` tidak aman untuk digunakan secara konkuren! +menggunakan sebuah `map`, tapi `map` tidak aman untuk digunakan secara +konkuren! .play concurrency/exercise-web-crawler.go diff --git a/content/flowcontrol.article b/content/flowcontrol.article index 0cc3866..e344e72 100644 --- a/content/flowcontrol.article +++ b/content/flowcontrol.article @@ -156,7 +156,7 @@ Sebagai contoh, tidak akan memanggil fungsi `f` jika `i==0`. -#appengine: *Catatan:* waktu dalam Go playground selalu berawal dari +#appengine: *Catatan:* Waktu dalam Go playground selalu berawal dari #appengine: 2009-11-10 23:00:00 UTC, sebuah nilai yang maknanya bisa dicari #appengine: oleh pembaca. diff --git a/content/methods.article b/content/methods.article index 4383c0f..31e72b9 100644 --- a/content/methods.article +++ b/content/methods.article @@ -51,10 +51,10 @@ Hal ini berarti tipe _receiver_ memiliki sintaks `*T` untuk tipe `T`. Sebagai contohnya, method `Scale` didefinisikan pada `*Vertex`. -Method dengan pointer-receiver dapat mengubah nilai yang diacu oleh receiver -(seperti yang dilakukan oleh `Scale`). -Karena method seringkali perlu mengubah receiver-nya, _pointer-receiver_ lebih -umum ditemukan daripada _receiver_ yang bukan pointer. +Method dengan _pointer-receiver_ dapat mengubah nilai yang ditunjuk (seperti +yang dilakukan oleh `Scale`). +Karena method terkadang perlu mengubah _receiver_ nya, _pointer-receiver_ +lebih umum digunakan daripada _receiver_ dengan value. Coba hapus `*` dari deklarasi fungsi `Scale` pada baris 16 dan perhatikan bagaimana perilaku program berubah. @@ -151,7 +151,8 @@ nilai atau sebagai pointer, tapi tidak gabungan dari keduanya. Sebuah _type_interface_ didefinisikan sebagai sebuah kumpulan method penanda. -Nilai dari tipe interface dapat menyimpan nilai apapun yang mengimplementasikan method tersebut. +Nilai dari tipe interface dapat menyimpan nilai apapun yang +mengimplementasikan method tersebut. *Catatan:* Terdapat kesalahan di contoh kode pada baris 22. `Vertex` (tipe nilai) tidak memenuhi `Abser` karena method `Abs` hanya @@ -189,10 +190,10 @@ dengan nama yang sama pada tipe yang dipegangnya. Jika nilai sebenarnya dari interface itu sendiri adalah nil, method akan dipanggil dengan receiver bernilai nil. -Pada beberapa bahasa pemrograman hal ini akan mengakibatkan null pointer -exception atau kesalahan karena pointer bernilai kosong, tapi pada Go sangat -umum menulis method dengan receiver bernilai nil (seperti method `M` pada -contoh di sebelah.) +Pada beberapa bahasa pemrograman hal ini akan mengakibatkan +`null`pointer`exception` atau kesalahan karena pointer bernilai kosong, tapi +pada Go sangat umum menulis method dengan receiver bernilai nil (seperti +method `M` pada contoh di sebelah.) Ingatlah bahwa sebuah isi interface yang mengandung nilai konkrit nil sebenarnya adalah non-nil. @@ -304,7 +305,8 @@ nilai. * Latihan: Stringer -Buat tipe `IPAddr` yang mengimplementasikan `fmt.Stringer` untuk mencetak alamat dengan empat tanda titik. +Buat tipe `IPAddr` yang mengimplementasikan `fmt.Stringer` untuk mencetak +alamat dengan empat tanda titik. Misalnya, `IPAddr{1,`2,`3,`4}` mengeluarkan `"1.2.3.4"`. @@ -320,9 +322,11 @@ Tipe `error` adalah interface buatan mirip dengan `fmt.Stringer`: Error() string } -Seperti dengan `fmt.Stringer`, paket `fmt` mencari interface `error` saat mencetak nilai. +Seperti dengan `fmt.Stringer`, paket `fmt` mencari interface `error` saat +mencetak nilai. -Fungsi terkadang mengembalikan nilai `error`, dan kode yang memanggilnya harus menangani error dengan memeriksa apakah error bernilai `nil`. +Fungsi terkadang mengembalikan nilai `error`, dan kode yang memanggilnya harus +menangani error dengan memeriksa apakah error bernilai `nil`. i, err := strconv.Atoi("42") if err != nil { @@ -331,7 +335,8 @@ Fungsi terkadang mengembalikan nilai `error`, dan kode yang memanggilnya harus m } fmt.Println("Converted integer:", i) -`error` yang nil menandakan sukses; `error` yang bukan-nil menandakan adanya kesalahan. +`error` yang nil menandakan sukses; `error` yang bukan-nil menandakan adanya +kesalahan. .play methods/errors.go @@ -341,7 +346,8 @@ Salin fungsi `Sqrt` anda dari [[/flowcontrol/8][latihan sebelumnya]] dan ubah untuk mengembalikan nilai `error`. -`Sqrt` seharusnya mengembalikan nilai error bukan-nil saat diberikan angka negatif, karena tidak mendukung bilangan kompleks. +`Sqrt` seharusnya mengembalikan nilai error bukan-nil saat diberikan angka +negatif, karena tidak mendukung bilangan kompleks. Buatlah tipe baru @@ -351,20 +357,23 @@ dan buat dia sebagai `error` dengan memberikan method func (e ErrNegativeSqrt) Error() string -sehingga `ErrNegativeSqrt(-2).Error()` mengembalikan `"cannot`Sqrt`negative`number:`-2"`. +sehingga `ErrNegativeSqrt(-2).Error()` mengembalikan +`"cannot`Sqrt`negative`number:`-2"`. *Catatan:* Pemanggilan `fmt.Sprint(e)` di dalam method `Error` akan membuat program berulang tak henti. -Anda dapat menghindari hal tersebut dengan mengkonversi `e`: `fmt.Sprint(float64(e))`. -_Kenapa?_ +Anda dapat menghindari hal tersebut dengan mengkonversi `e`: +`fmt.Sprint(float64(e))`. _Kenapa?_ -Ubah fungsi `Sqrt` mengembalikan nilai `ErrNegativeSqrt` saat diberikan nilai negatif. +Ubah fungsi `Sqrt` mengembalikan nilai `ErrNegativeSqrt` saat diberikan nilai +negatif. .play methods/exercise-errors.go * Reader -Paket `io` memiliki spesifikasi interface `io.Reader`, yang merepresentasikan berakhirnya pembacaan sebuah aliran data. +Paket `io` memiliki spesifikasi interface `io.Reader`, yang merepresentasikan +berakhirnya pembacaan sebuah aliran data. Standar pustaka Go memiliki [[https://golang.org/search?q=Read#Global][banyak implementasi]] @@ -375,7 +384,8 @@ Interface `io.Reader` memiliki method `Read`: func (T) Read(b []byte) (n int, err error) -`Read` mengisi parameter slice byte dengan data dan mengembalikan jumlah byte yang diisi dan nilai errornya. +`Read` mengisi parameter slice byte dengan data dan mengembalikan jumlah +byte yang diisi dan nilai errornya jika ada. Ia mengembalikan error `io.EOF` saat aliran data berakhir. Contoh kode membuat sebuah @@ -386,7 +396,8 @@ dan memproses 8 bytes keluarannya. * Latihan: Reader -Implementasikan sebuah tipe `Reader` yang menghilangkan karakter ASCII `'A'` yang panjang. +Implementasikan sebuah tipe `Reader` yang menghilangkan karakter ASCII `'A'` +yang panjang. .play methods/exercise-reader.go @@ -394,11 +405,14 @@ Implementasikan sebuah tipe `Reader` yang menghilangkan karakter ASCII `'A'` yan Pola umumnya adalah sebuah [[https://golang.org/pkg/io/#Reader][io.Reader]] -yang membungkus `io.Reader` lainnya, memodifikasi aliran data dengan cara tertentu. +yang membungkus `io.Reader` lainnya, memodifikasi aliran data dengan cara +tertentu. Sebagai contohnya, fungsi [[https://golang.org/pkg/compress/gzip/#NewReader][gzip.NewReader]] -mengambil `io.Reader` (aliran data terkompres) dan mengembalikan `*gzip.Reader` yang juga mengimplementasikan `io.Reader` (aliran data tak-terkompres). +mengambil `io.Reader` (aliran data terkompres) dan mengembalikan +`*gzip.Reader` yang juga mengimplementasikan `io.Reader` (aliran data +tak-terkompres). Implementasikan `rot13Reader` yang mengimplementasikan `io.Reader` dengan membaca dari `io.Reader`, modifikasi aliran data dengan menerapkan penyandian @@ -441,7 +455,8 @@ Interface dan tipe tersebut dispesifikasikan oleh * Latihan: Gambar -Masih ingat generator gambar yang anda buat sebelumnya? +Masih ingat dengan [[/moretypes/18][generator gambar]] yang anda buat +sebelumnya? Mari kita buat satu lagi, tapi kali ini mengembalikan implementasi dari `image.Image` bukan sebuah slice dari data. @@ -449,12 +464,14 @@ Definisikan tipe `Image` anda sendiri, kemudian implementasikan [[https://golang.org/pkg/image/#Image][method-method yang dibutuhkan]] , dan panggil `pic.ShowImage`. -`Bounds` seharusnya mengembalikan `image.Rectangle`, seperti `image.Rect(0,`0,`w,`h)`. +`Bounds` seharusnya mengembalikan `image.Rectangle`, seperti +`image.Rect(0,`0,`w,`h)`. `ColorModel` seharusnya mengembalikan `color.RGBAModel`. `At` seharusnya mengembalikan sebuah warna; -nilai `v` pada generator gambar berkoresponden dengan `color.RGBA{v,`v,`255,`255}`. +nilai `v` pada generator gambar berkoresponden dengan +`color.RGBA{v,`v,`255,`255}`. .play methods/exercise-images.go diff --git a/content/moretypes.article b/content/moretypes.article index f9f3da4..74d2ce8 100644 --- a/content/moretypes.article +++ b/content/moretypes.article @@ -60,7 +60,8 @@ mengaksesnya langsung dengan `p.X` tanpa membutuhkan penunjukan ulang. Sebuah `struct` bisa dibuat dengan mengisinya dengan nilai bagian-bagiannya. -Anda juga bisa mengisi hanya sebagian dari kolom dengan menggunakan sintaks `Name:` (urutan dari bagian-bagiannya tidak berpengaruh). +Anda juga bisa mengisi hanya sebagian dari kolom dengan menggunakan sintaks +`Name:` (urutan dari bagian-bagiannya tidak berpengaruh). Prefik `&` mengembalikan sebuah pointer ke `struct`. @@ -69,7 +70,8 @@ Prefik `&` mengembalikan sebuah pointer ke `struct`. * Array -Deklarasi tipe dengan `[n]T` adalah untuk array dengan jumlah `n` dan bertipe `T`. +Deklarasi tipe dengan `[n]T` adalah untuk array dengan jumlah `n` dan bertipe +`T`. Ekspresi @@ -77,7 +79,8 @@ Ekspresi mendeklarasikan sebuah variabel `a` sebagai sebuah array dari sepuluh integer. -Panjang sebuah array adalah bagian dari tipenya, jadi array tidak bisa diubah ukurannya. +Panjang sebuah array adalah bagian dari tipenya, jadi array tidak bisa diubah +ukurannya. Hal ini sepertinya membatasi, tapi jangan khawatir; Go menyediakan cara yang mudah untuk bekerja dengan array. @@ -277,7 +280,8 @@ Fungsi menarik yang bisa diikutkan berupa `(x+y)/2`, `x*y`, dan `x^y`. Petunjuk: -- Anda membutuhkan penggunaan sebuah pengulangan untuk mengalokasi `[]uint8` di dalam `[][]uint8`. +- Anda membutuhkan penggunaan sebuah pengulangan untuk mengalokasi `[]uint8` +di dalam `[][]uint8`. - Gunakan `uint8(intValue)` untuk mengkonversi antara tipe. @@ -343,8 +347,10 @@ bentuk deklarasi singkat berikut: * Latihan: map Implementasikan `WordCount`. -Fungsi tersebut mengembalikan sebuah map dari penghitungan setiap "kata" di dalam string `s`. -Fungsi `wc.Test` menjalankan pengujian terhadap fungsi yang diberikan dan mencetak sukses atau salah. +Fungsi tersebut mengembalikan sebuah map dari penghitungan setiap "kata" di +dalam string `s`. +Fungsi `wc.Test` menjalankan pengujian terhadap fungsi yang diberikan dan +mencetak sukses atau salah. Anda mungkin menemukan artikel berikut [[https://golang.org/pkg/strings/#Fields][strings.Fields]] @@ -357,15 +363,16 @@ membantu anda. Fungsi adalah suatu nilai juga. Fungsi dapat dikirimkan kemanapun seperti nilai lainnya. -Nilai fungsi bisa digunakan sebagai argumen pada fungsi dan sebagai nilai -kembalian. +Nilai fungsi bisa digunakan sebagai argumen pada fungsi lainnya dan sebagai +nilai kembalian. .play moretypes/function-values.go * Fungsi closure Fungsi pada Go bisa _closure_. -_Closure_ adalah sebuah nilai fungsi yang merujuk variabel dari blok fungsinya. +_Closure_ adalah sebuah nilai fungsi yang merujuk variabel dari blok +fungsinya. Fungsi closure bisa mengakses dan mengisi variabel yang dirujuk; dalam artian fungsi tersebut "terikat" ke variabel. diff --git a/content/welcome.article b/content/welcome.article index 7e9b293..67efd2b 100644 --- a/content/welcome.article +++ b/content/welcome.article @@ -26,7 +26,7 @@ Anda bisa menavigasinya lewat - [[javascript:highlight(".next-page")]["selanjutnya"]] atau `PageDown` untuk ke halaman selanjutnya. Tur ini interaktif. Klik pada tombol -[[javascript:highlightAndClick("#run")][Jalankan]] +[[javascript:highlightAndClick("#run")][Jalan]] sekarang (atau tekan `Shift` + `Enter`) untuk mengkompilasi dan menjalankan program pada #appengine: server. |
