จาก Part 1 เกี่ยวกับการพัฒนาภาษา Go จำนวน 10 เรื่องแรก
เน้นไปที่การใช้งาน short declaration variable
มาต่อกับ Part 2 อีก 10 เรื่อง เน้นในเรื่องของการใช้งาน String, Array, Slice และ Map
มาเริ่มกันเลย
เรื่องที่ 11 ตัวแปรชนิด string ไม่สามารถกำหนดค่าให้เป็น nil ได้
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="11.go"]เรื่องที่ 12 การส่งข้อมูลชนิด array ผ่าน function
สำหรับนักพัฒนาภาษา C/C++ นั้น ข้อมูลชนิด array คือ pointer
นั่นคือ เมื่อเราส่ง array ไปยัง function
สิ่งเกิดขึ้นคือ เราทำการส่ง pointer หรือตำแหน่งบน memory ไป
ดังนั้น เมื่อ function ทำการเปลี่ยนแปลงค่าของ array แล้ว จะกระทบกับต้นทางเสมอ
แต่ในภาษา go แตกต่าง เพราะว่าการส่งข้อมูลชนิด array ไปยัง function
มันคือการ copy value ของ array
ดังนั้น ถ้าใน function ทำการแก้ไขค่าของ array จะไม่กระทบต้นทางเลย
ซึ่งตรงนี้อาจจะทำให้นักพัฒนาที่เริ่มต้นกับภาษา go สับสนได้ง่าย
แต่ถ้าต้องการให้ใน function ทำการแก้ไขค่า array และต้นทางเปลี่ยนแปลง
ต้องส่ง pointer ของ array เข้ามา ดังนี้
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="12.go"]
หรือสามารถใช้งาน slice ได้เช่นกัน ดังนี้
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="122.go"]
เรื่องที่ 13 ข้อควรระวังในการใช้ range กับ slice และ array
ข้อควรระวังในการวน loop ด้วยคำสั่ง for ซึ่งมักจะใช้ร่วมกับ range
โดยที่ค่าที่ return กลับมาจาก range มี 2 ค่าคือ index กับ value
สิ่งที่ผิดพลาดมาก ๆ คือ ประกาศตัวแปรมารับเพียงค่าเดียว
ซึ่งจะได้ค่า index นั่นเอง ไม่ใช่ค่าของ value !!
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="13.go"]
เรื่องที่ 14 การเข้าถึง key ที่ไม่มีใน Map
ถ้าเป็นภาษาโปรแกรมอื่น ๆ แล้ว
ถ้าเราต้องเข้าถึงหรือดึงข้อมูลจาก Map ด้วย key ที่ไม่ม่ีใน Map
ผลที่น่าจะต้องได้มาคือ nil หรือไม่พบข้อมูลนั่นเอง
แต่ไม่ใช่ในภาษา go
เนื่องจาก Map ในภาษา go จะ return zero value กลับมาเมื่อไม่พบข้อมูล
ค่าที่ return กลับมาสามารถมีค่าเป็น nil, empty string, false และ 0
ดังนั้นค่าที่ return กลับมานี้ ไม่สามารถนำมาใช้ในการตัดสินใจได้
เพราะว่าอาจจะทำให้เกิดข้อผิดพลาดได้
ยกตัวอย่างเช่น value ของ key=two ใน Map มีค่าเป็น empty string
จากนั้นนำ value ที่ได้มาตรวจสอบ อาจจะทำให้เกิดข้อผิดพลาดได้
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="14.go"]
เรื่องท่ี 15 Strings are immutable
นั่นคือตัวแปรชนิด string ไม่สามารถแก้ไขข้อมูลได้
ถ้าเราพยายามแก้ไขข้อมูลบางตำแหน่งใน string แล้ว
ผลที่ได้คือ compile ไม่ผ่าน เพราะว่า string คือ read-only byte slice นั่นเอง
แต่ถ้าเราต้องการแก้ไข สามารถใช้ byte slice แทนได้ ดังตัวอย่าง
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="15.go"]
แต่ code นี้จะไม่สามารถใช้งานได้กับข้อมูลท่ีเก็บข้อมูลมากกว่า 1 byte
ยกตัวอย่างเช่นภาษาไทย และ ภาษาจีน เป็นต้น
ดังนั้นจำเป็นต้องแปลงไปเป็น rune slide ก่อน
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="152.go"]
เรื่องท่ี 16 การแปลงข้อมูลระหว่าง string และ byte slice
ในภาษา go นั้นเมื่อทำการแปลงข้อมูลไปมาระหว่าง string และ byte slice นั้น
เป็นการ copy ข้อมูลกันจริง ๆ ไม่ใช่เป็นการ cast type เหมือนภาษาอื่น ๆ
และไม่เหมือนการ reslice ที่ slice ใหม่ยังชี้ไปยังที่เดียวกันกับ slice ต้นฉบับ
โดยภาษา go นั้นได้ทำการ optimization เรื่องการแปลงข้อมูลไว้อย่างดี
เพื่อลดการจองพื้นที่ในหน่วยความจำ
เรื่องท่ี 17 การเข้าถึงข้อมูลของ string
ในการเข้าถึงข้อมูลแต่ละตำแหน่งของ string จะใช้งาน index operator
ซึ่งจะ return ข้อมูลชนิด byte กลับมา ไม่ใช่ character
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="17.go"]
แต่ถ้าต้องการเข้าถึงแต่ละตำแหน่งของ string
ให้ได้ค่าเป็น character (unicode code point หรือ rune) แล้ว
สามารถใช้งาน for-range ได้
หรือใช้งานผ่าน package unicode/utf8
หรือใช้งานผ่าน package utf8string จะมีfunction At() ให้งาน
หรือทำการแปลง string เป็น slice ของ rune ก็ได้
เรื่องท่ี 18 ค่าใน string ไม่จำเป็นต้องเป็น UTF-8 เสมอไป
โดยที่เราสามารถตรวจสอบค่าใน string ได้ด้วยว่าเป็น UTF-8 หรือไม่
ด้วย function ValidString() จาก package unicode/utf8
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="18.go"]
เรื่องท่ี 19 ความยาวของข้อมูลชนิด string
ในภาษา go นั้นเรื่องความยาวของ string จะต่างจากภาษาอื่น
โดยถ้าใช้งานผ่าน function len() แล้ว ผลที่ได้คือ
จำนวนของ byte ไม่ใช้จำนวนของ character ทำให้ผลลัพธ์ที่ได้ต่างไปดังนี้
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="19.go"]
จาก code ข้างต้นจะได้ความยาวเท่ากับ 3
นั่นหมายความว่าข้อมูลมี 3 byte นั่นเอง
แต่ถ้าต้องการให้ return เป็น 1 ตามจำนวนของ character ที่เห็นจริง ๆ
ต้องใช้งานผ่าน function RuneCountInString() จาก package unicode/utf8 ดังนี้
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="192.go"]
ในเชิงลึกแล้วนั้น function RuneCountInString()
นั้นไม่ได้ return จำนวนของ character
แต่มันคือจำนวนของ rune ซึ่ง 1 character นั้นอยู่บน rune มากกว่า 1 ได้
ยกตัวอย่างเช่น
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="193.go"]
เรื่องท่ี 20 อย่าลืมใส่ comma (,) ใน multi-line slice, array และ map ด้วย มิเช่นนั้นจะ compile ไม่ผ่าน
[gist id="8bdf9e24d4efa14e2e95d793e4074c5f" file="20.go"]