1 พื้นฐานของฟังก์ชัน
ในโปรแกรมมิ่ง ฟังก์ชันคือชิ้นส่วนของโค้ดที่ทำงานเพื่อกระทำงานที่เฉพาะเจาะจงและสามารถมีพารามิเตอร์ของข้อมูลนำเข้าและคืนค่าได้ ใน Go language ฟังก์ชันถูกใช้กันอย่างแพร่หลายเพื่อจัดระเบียบและนำโค้ดไปใช้ซ้ำ การใช้งานฟังก์ชันได้อย่างมีประสิทธิภาพจะทำให้โค้ดมีขนาดกระชับมากขึ้น อ่านและบำรุงรักษาได้ง่ายขึ้นด้วย
ฟังก์ชันเป็นส่วนหนึ่งที่สำคัญของ Go language และความเข้าใจในการประกาศและกำหนดฟังก์ชันมีความสำคัญสำหรับการเขียนโค้ดที่มีประสิทธิภาพและอ่านง่าย
2 การกำหนดฟังก์ชัน
2.1 การประกาศฟังก์ชัน
ใน Go language รูปแบบทั่วไปของการประกาศฟังก์ชันคือ:
func ชื่อฟังก์ชัน(พารามิเตอร์) ประเภทการคืนค่า {
// โค้ดของฟังก์ชัน
}
มาชิ้ชิเสี่ยวว่า:
- คีย์เวิร์ด
func
ถูกใช้เพื่อประกาศฟังก์ชัน -
ชื่อฟังก์ชัน
คือชื่อของฟังก์ชัน ตามกฎการตั้งชื่อใน Go language ฟังก์ชันที่มีตัวอักษรตัวพิมพ์ใหญ่ขึ้นต้นสามารถใช้งานได้ซึ่งหมายความว่าสามารถมองเห็นจากภายนอกของแพคเกจ ฟังก์ชันที่มีตัวอักษรตัวพิมพ์เล็กขึ้นต้นสามารถใช้ได้เฉพาะภายในแพคเกจถึงแต่ว่านอกแพคเกจ -
พารามิเตอร์
คือรายการของพารามิเตอร์ที่ฟังก์ชันรับ ที่แยกกันด้วยเครื่องหมายจุลภาค จะต้องระบุประเภทของแต่ละพารามิเตอร์ และหากมีหลายพารามิเตอร์ที่มีประเภทเดียวกัน ประเภทอาจถูกระบุไว้เพียงครั้งเดียวเท่านั้น -
ประเภทการคืนค่า
คือประเภทของค่าที่ฟังก์ชันคืนค่าออกมา หากฟังกชันไม่ได้คืนค่า ส่วนนี้สามารถถูกข้ามได้ และหากฟังก์ชันคืนค่าหลายตัว จะต้องถูกครอบด้วยวงเล็บ
เช่น เราสามารถประกาศฟังก์ชันง่ายๆ เพื่อคำนวณผลรวมของจำนวนเต็มสองตัวได้ดังนี้:
func Add(a int, b int) int {
return a + b
}
ในตัวอย่างนี้ ชื่อของฟังก์ชันคือ Add
, มีพารามิเตอร์สองตัว คือ a
และ b
ซึ่งมีประเภท int
และคืนค่าเป็นผลรวมของพารามิเตอร์สองตัวด้วยประเภทเป็น int
2.2 รายการของพารามิเตอร์
รายการของพารามิเตอร์กำหนดว่าฟังก์ชันนำเข้าพารามิเตอร์ชนิดใด ๆ และไม่ใช่ข้อมูลปกติ พารามิเตอร์คือตัวแปรประเภทพิเศษที่ใช้ในการส่งข้อมูลไปยังฟังก์ชัน
func Greet(name string, age int) {
fmt.Printf("สวัสดี, %s! คุณมีอายุ %d ปี\n", name, age)
}
ในฟังก์ชัน Greet
นี้ name
และ age
คือพารามิเตอร์ ประเภทของ name
คือ string
และประเภทของ age
คือ int
เมื่อเรียกใช้ฟังก์ชันนี้ ค่าจริงจะต้องถูกให้สำหรับพารามิเตอร์เหล่านี้
2.3 ประเภทของการคืนค่า
ฟังก์ชันสามารถคืนผลลัพธ์ที่คำนวณได้ และประเภทการคืนค่ากำหนดประเภทของค่าการคืนของฟังก์ชัน ฟังก์ชันสามารถไม่ต้องคืนค่า หรือสามารถมีค่าการคืนตัวแปรเดียวหรือมากกว่า
หากฟังก์ชันมีการคืนไปหลายค่า ประเภทของสิ่งที่คืนจะต้องถูกครอบด้วยวงเล็บในขณะประกาศ:
func Divide(dividend, divisor float64) (float64, error) {
if divisor == 0 {
return 0, errors.New("ไม่สามารถหารด้วยศูนย์ได้")
}
return dividend / divisor, nil
}
ฟังก์ชัน Divide
ที่นี่คืนค่าสองค่า คือ ผลหาร และข้อความข้อผิดพลาด หากตัวหารเป็นศูนย์
2.4 พารามิเตอร์แบบต่างๆ
ใน Golang เมื่อเราไม่แน่ใจว่าผู้เรียกจะส่งพารามิเตอร์จำนวนเท่าไหนเมื่อกำหนดฟังก์ชัน เราสามารถใช้พารามิเตอร์แบบต่างๆ ได้ ที่แสดงด้วยเครื่องหมาย ellipsis ...
ซึ่งหมายความว่าฟังก์ชันสามารถรับพารามิเตอร์จำนวนใดๆ หากต้องการใช้ข้อมูลไม่แน่นอนหรือการทำงานบางประการอย่างการจัดรูปแบบ การสรุปหรือการวนซ้ำ
ฉากในการประยุกต์ใช้
พารามิเตอร์แบบต่างๆ มักถูกใช้อย่างแพร่หลายในสถานการณ์ต่อไปนี้:
-
การต่อข้อความ: เช่นฟังก์ชัน
fmt.Sprintf
และstrings.Join
- การประมวลผลรายการ/สไลซ์: เมื่อประมวลผลรายการหรือสไลซ์ที่มีความยาวที่แตกต่างกัน เช่นการคำนวณผลรวมหรือการต่อข้อความรายการหลายชิ้น
-
การบันทึกข้อความผิดพลาดและการจัดการข้อผิดพลาด: เมื่อจัดการกับข้อผิดพลาดหลายข้อ หรือบันทึกข้อมูลบันทึกข้อผิดพลาดหลายส่วน เช่น
log.Printf
หรือฟังก์ชันสรุปข้อผิดพลาดเอง - ฟังก์ชันช่วยเหลือ: ใช้ใน APIs หรือไลบรารีเพื่อให้ผู้ใช้มีวิธีการเรียกฟังก์ชันได้แบบที่ยืดหยุ่นมากขึ้น
การใช้พารามิเตอร์แปรผัน
นี่คือตัวอย่างง่ายๆ ของการใช้พารามิเตอร์แปรผัน:
// กำหนดฟังก์ชันที่รับพารามิเตอร์จำนวนเต็มแปรผันและส่งค่าผลรวมของพวกเขากลับ
func Sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
func main() {
// คุณสามารถส่งพารามิเตอร์จำนวนใดก็ได้
fmt.Println(Sum(1, 2)) // ผลลัพธ์: 3
fmt.Println(Sum(1, 2, 3, 4)) // ผลลัพธ์: 10
// คุณยังสามารถส่ง slice และใช้ ellipsis หลังจาก slice ด้วย
numbers := []int{1, 2, 3, 4, 5}
fmt.Println(Sum(numbers...)) // ผลลัพธ์: 15
}
ในฟังก์ชัน Sum
เราใช้ nums
เป็น slice ของจำนวนเต็มที่มีพารามิเตอร์ทั้งหมดที่ส่งไปยังฟังก์ชัน Sum
โดยเราสามารถใช้ลูป range เพื่อวนลูปผ่าน slice นี้และคำนวณผลรวม
ควรระวังว่าพารามิเตอร์แปรผันภายในฟังก์ชันจริงๆแล้วเป็น slice ดังนั้นสามารถใช้การดำเนินการที่เกี่ยวข้องกับ slice ได้ทั้งหมด ในกรณีที่ต้องการส่ง slice เป็นพารามิเตอร์แปรผันไปยังฟังก์ชัน เพียงแค่เพิ่ม ellipsis ...
หลัง slice
การใช้พารามิเตอร์แปรผันสามารถทำให้การเรียกใช้ฟังก์ชันเป็นไปอย่างยืดหยุ่นและกระชับ แต่มันก็จะมีผลต่อประสิทธิภาพเล็กน้อย เนื่องจากการใช้พารามิเตอร์แปรผันอาจมีการสร้าง slice และการจัดสรรหน่วยความจำ ดังนั้นควรระมัดระวังเมื่อมีข้อกำหนดทางการทำงานที่เข้มงวด
เคล็ดลับ: การอธิบายเพิ่มเติมเกี่ยวกับ slice จะถูกให้ในบทต่อไป ถ้าคุณมีประสบการณ์กับภาษาโปรแกรมอื่น ๆ คุณสามารถคิดเสมือนว่ามันคืออาร์เรย์ชั่วคราวได้ชั่วคราว
3 เรียกใช้ฟังก์ชัน
3.1 การเรียกใช้ฟังก์ชันพื้นฐาน
การเรียกใช้งานฟังก์ชันหมายถึงการดำเนินการของโค้ดของฟังก์ชัน ใน Go การเรียกใช้ฟังก์ชันที่ถูกกำหนดไว้อย่างง่ายดาย แค่ใช้ชื่อฟังก์ชันและส่งพารามิเตอร์ที่เหมาะสม เช่น:
result := add(3, 4)
fmt.Println(result) // ผลลัพธ์: 7
ในตัวอย่างนี้ ฟังก์ชัน add
ถูกเรียกและจำนวนเต็มสองจำนวนถูกส่งไปเป็นพารามิเตอร์ และจากนั้นผลลัพธ์ที่ได้กำหนดให้กับตัวแปร result
3.2 การส่งพารามิเตอร์
เมื่อส่งพารามิเตอร์ไปยังฟังก์ชัน ใน Go มีค่าเริ่มต้นที่จะใช้การส่งโดยค่า (pass-by-value) ซึ่งหมายความว่าการส่งสำเนาของค่าพารามิเตอร์ และข้อมูลต้นฉบับจะไม่เปลี่ยนแปลง อย่างไรก็ตาม หากคุณต้องการให้ฟังก์ชันแก้ไขตัวแปรภายนอกหรือเพื่อเหตุผลด้านประสิทธิภาพ คุณสามารถใช้ pass-by-reference เช่นการใช้อินเทอร์หรือการส่ง struct ขนาดใหญ่
นี่คือตัวอย่างของ pass-by-value และ pass-by-reference:
// ตัวอย่างของ pass-by-value
func double(val int) {
val *= 2
}
// ตัวอย่างของ pass-by-reference
func doublePtr(val *int) {
*val *= 2
}
func main() {
value := 3
double(value)
fmt.Println(value) // ผลลัพธ์คือ 3, ค่า value ยังคงเดิมเหมือนเดิม
doublePtr(&value)
fmt.Println(value) // ผลลัพธ์คือ 6, ค่า value ดูเลยเจรบเปลี่ยนไปเท่าสองเท่า
}
ในตัวอย่างด้านบน ฟังก์ชัน double
พยายามที่จะคูณค่า val
ที่ส่งมา แต่มันเพียงแค่คูณสำเนา ซึ่งทำให้ตัวแปร value
ต้นฉบับไม่เปลี่ยน อย่างไรก็ตาม ฟังก์ชัน doublePtr
ทำการเปลี่ยนค่าของตัวแปรต้นฉบับโดยรับพอยน์เตอร์ไปยังตัวแปรจำนวนเต็ม เช่น