อธิบาย Exercise: Slices ใน A Tour of Go
Published: 2022-03-03 05:16:19

หากใครได้ลองเล่น A Tour of Go บทที่ว่าด้วยเรื่อง Slice แล้วไปเจอ Exercise ในตำนาน ที่มือใหม่แทบทุกคนจะไม่กด Run แต่ไปกด > เพื่อผ่านไปหน้าถัดไปตัวนี้ https://go.dev/tour/moretypes/18

ความจริงโจทย์นี้ถึงจะมีคำอธิบาย แต่ก็แอบเข้าใจยากอยู่ดี บางคนอ่านแล้วอ่านอีกก็ยังไม่เก็ต ว่าเอ็งต้องการอะไรฟระ ก็เลยอยากจะลองอธิบายอย่างละเอียดดูว่าจะช่วยอะไรได้บ้าง

```go
package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
}

func main() {
	pic.Show(Pic)
}
```

โจทย์นี้ มือใหม่หลายท่านจะสงสัยมากตั้งแต่เห็น `pic.Show(Pic)` ว่ามันคืออะไร แล้วจิตใจก็ไปจดจ่ออยู่ตรงนั้น อันนี้ผมแนะนำว่า ให้เอากระดาษมาแปะปิดมันเอาไว้ เราจะได้ไม่ต้องไปเห็นมันครับ
เพราะงานที่เราควรทำคือ ไปเขียนโค้ดใน `func Pic(dx, dy int) [][]uint8` ด้านบนแค่นั้นเลย อย่าไปยุ่งกับตรงอื่น

ผมจะเริ่มจากอธิบายโจทย์ให้อ่านก่อนอีกสักรอบแบบขยายความว่า

จงเขียนฟังก์ชัน Pic ให้เสร็จ โดยหน้าที่ของ Pic คือการสร้างเม็ดสีให้กับสี่เหลี่ยมใดๆ ซึ่งตัวฟังก์ชัน Pic รับ parameter มา 2 ตัวคือ dx ซึ่งเป็นตัวแทนของความกว้างตามแนวแกน x ของรูป และค่า dy ค่าตัวแทนของความสูงของรูปตามแนวแกน y และเราไม่จำเป็นต้องรู้เลยว่า dx และ dy นั้นเป็นเลขอะไร (ไม่สำคัญกับเราเลย)

เพราะเราได้ค่าเข้ามาเป็นตัวแปรแล้ว เราสามารถเอามาใช้ได้เลย
และสิ่งที่เราจะต้องทำคือ หาทางสร้างเม็ดสีให้กับสี่เหลี่ยมรูปนี้ แล้วโปรแกรมจะเอาเม็ดสีนี้ไปวาดรูปให้เรา ซึ่งสุดท้ายแล้ว รูปที่ได้ จะเป็นรูปที่มีสีแบบ gray scale แต่เป็นสีฟ้าอมน้ำเงินนะ

ในโจทย์จะมี hint ให้  2 ประโยคคือ

- คุณจะต้องวนลูปเพื่อเอา []uint8 แต่ละชิ้นใส่เข้าไปใน [][]uint8
- หากต้องการจะแปลง type ของ int ไปเป็น uint8 ก็แค่เอา uint8(int) ครอบค่า int ลงไปได้เลย


ผมขอแก้ข้อสงสัยของทุกคนก่อนเรื่อง

```go
func main() {
	pic.Show(Pic)
}
```

คือ Show เนี่ย มันเป็นฟังก์ชันที่เรา import เข้ามาจาก "golang.org/x/tour/pic" ด้านบนครับ ซึ่งมันเป็น [Higher Order Function ](https://dev.to/pallat/hof-in-go-18mm)ทำให้มันรับเอาฟังก์ชัน Pic ของเราเข้าไปเป็น parameter ได้นั่นเอง

ประการต่อมาคือ ในโจทย์เขาให้สูตรมา 3 สูตร แล้วบอกเราว่า ถ้าลองใช้สูตรพวกนี้จะทำให้ภาพที่ได้มีความน่าสนใจ

หลายๆคนพออ่านตรงนี้ก็จะเกิดคำถามว่า x กับ y มาจากไหน?


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4azr57b9uuxwn63ie06.png)

ให้ดูจากรูปนะครับว่า parameter ที่เขาใส่เข้ามาใน Pic คือ dx และ dy ส่วนค่า x ก็คือค่าของพิกเซลในแนวแกน x ตั้งแต่ index ที่ 0 ไปจนถึง dx-1 หรือจะคิดว่าเป็น ตัวที่ 1 ถึง dx ก็ได้เช่นกัน
ส่วน y ก็คือค่าของแต่ละ row ในแนวแกน y ตั้งแต่ 1 ถึง dy หรือถ้าคิดแบบ index ใน array ก็คือตัวที่ 0 ถึง dy-1 นั่นเอง

ซึ่งหน้าที่ของเราในการเขียนโปรแกรมคือต้องสร้างเม็ดสีในแนวแกน x ให้ได้ก่อน จำนวน dx ตัว ซึ่งจะได้ type เป็น []uint8 ในภาษา Go โดยผมจะตั้งชื่อให้มันว่า row ก็แล้วกัน และเราต้องสร้าง row นี้ออกมาให้ได้จำนวน dy ตัว

เมื่อนำ row ที่มี type เป็น []uint8 มารวมเรียงต่อกัน มันก็จะกลายเป็น array ซ้อน array หรือก็คือ slice ซ้อน slice ใน Go ซึ่งก็จะได้ type เป็น [][]uint8 นั่นเอง

จากที่อธิบายมาข้างต้น ก็คงหนีไม่พ้นที่เราจะต้องวนลูป สร้างของพวกนี้ขึ้นมา โดยถ้าเราวนลูป dx ครั้ง ในแต่ละ iteration เราก็จะได้ค่า x ของแต่ละ iteration
และเมื่อวนลูป dy ครั้ง ในแต่ละ iteration เราก็จะได้ค่า y

และเราสามารถนำค่า x และ y ที่ได้มา ไปใช้ในสูตรทั้ง 3 สูตรตามโจทย์ได้เลยนั่นเอง

ผมขออธิบายเพียงเท่านี้ เพื่อให้เราสามารถนำไปแก้โจทย์ใน Tour ได้ด้วยตัวเอง และถ้าทำได้ถูกต้องเราก็จะได้เห็นรูปตามนี้รูปใดรูปหนึ่ง


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yevwbb6zlagnvmd4jya.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/io9d0fxyyok737123tct.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fgagk926fi14guk6hxjj.png)

หวังว่าจะสนุกกับการเขียน Go นะครับ