Skip to content

ค่าคงที่ใน Go

ค่าของค่าคงที่ไม่สามารถเปลี่ยนแปลงได้ในขณะรันไทม์ เมื่อกำหนดค่าแล้วไม่สามารถแก้ไขได้ ค่าของมันสามารถมาจาก

  • ตัวอักษร
  • ตัวระบุค่าคงที่อื่น
  • นิพจน์ค่าคงที่
  • การแปลงประเภทที่เป็นค่าคงที่
  • iota

ค่าคงที่ได้เฉพาะประเภทข้อมูลพื้นฐานเท่านั้น ไม่สามารถเป็น

  • ประเภทอื่นนอกเหนือจากประเภทพื้นฐาน เช่น สตรักเจอร์ อินเทอร์เฟซ สไลซ์ อาร์เรย์ เป็นต้น
  • ค่าที่ส่งคืนจากฟังก์ชัน

ค่าของค่าคงที่ไม่สามารถแก้ไขได้ มิฉะนั้นจะไม่สามารถผ่านการคอมไพล์

การเริ่มต้น

การประกาศค่าคงที่ต้องใช้คีย์เวิร์ด const ค่าคงที่ต้องเริ่มต้นด้วยค่าเมื่อประกาศ และประเภทของค่าคงที่สามารถละเว้นได้ เช่น

go
const name string = "Jack" // ตัวอักษร

const msg = "hello world" // ตัวอักษร

const num = 1 // ตัวอักษร

const numExpression = (1+2+3) / 2 % 100 + num // นิพจน์ค่าคงที่

หากเพียงแค่ประกาศโดยไม่กำหนดค่า จะไม่สามารถผ่านการคอมไพล์

go
const name string

คอมไพเลอร์รายงานข้อผิดพลาด

missing init expr for name

การประกาศค่าคงที่หลายตัวสามารถใช้ () ล้อมเพื่อเพิ่มความสามารถในการอ่าน สามารถมี () หลายชุดเพื่อให้ได้ผลของการจัดกลุ่ม

go
const (
   Count = 1
   Name  = "Jack"
)

const (
   Size = 16
   Len  = 25
)

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

go
const (
  A = 1
  B // 1
  C // 1
  D // 1
  E // 1
)

iota

iota เป็นตัวระบุค่าคงที่ในตัว มักใช้เพื่อแสดงลำดับจำนวนเต็มไม่มีประเภทในการประกาศค่าคงที่หนึ่งๆ โดยทั่วไปใช้ในวงเล็บ

go
const iota = 0

ดูตัวอย่างการใช้งานหลายตัวอย่าง

go
const (
   Num = iota // 0
   Num1 // 1
   Num2 // 2
   Num3 // 3
   Num4 // 4
)

สามารถเขียนแบบนี้ได้

go
const (
   Num = iota*2 // 0
   Num1 // 2
   Num2 // 4
   Num3 // 6
   Num4 // 8
)

ยังสามารถ

go
const (
   Num = iota << 2*3 + 1 // 1
   Num1 // 13
   Num2 // 25
   Num3 = iota // 3
   Num4 // 4
)

จากตัวอย่างข้างต้นจะพบว่า iota เพิ่มขึ้น นิพจน์ค่าของค่าคงที่แรกที่ใช้ iota จะกำหนดค่าให้กับค่าคงที่ถัดไปโดยอัตโนมัติตามการเปลี่ยนแปลงของค่าลำดับ จนกว่าจะรีเซ็ตด้วย const ใหม่ ลำดับนี้其实就是หมายเลขบรรทัดสัมพัทธ์ของโค้ด คือหมายเลขบรรทัดเริ่มต้นสัมพัทธ์กับการจัดกลุ่มปัจจุบัน ดูตัวอย่างด้านล่าง

go
const (
  Num  = iota<<2*3 + 1 // 1 บรรทัดแรก
  Num2 = iota<<2*3 + 1 // 13 บรรทัดที่สอง
  _ // 25 บรรทัดที่สาม
  Num3 //37 บรรทัดที่สี่
  Num4 = iota // 4 บรรทัดที่ห้า
  _ // 5 บรรทัดที่หก
  Num5 // 6 บรรทัดที่เจ็ด
)

ในตัวอย่างใช้ตัวระบุไม่ระบุชื่อ _ เพื่อใช้ตำแหน่งหนึ่งบรรทัด จะเห็นว่าค่าของ iota โดยพื้นฐานแล้วคือผลต่างระหว่างบรรทัดที่ iota อยู่กับบรรทัดแรกของการจัดกลุ่ม const ปัจจุบัน ส่วนการจัดกลุ่ม const ที่ต่างกันจะไม่ส่งผลกระทบต่อกัน

การแจงนับ

ภาษา Go ไม่ได้ออกแบบประเภทข้อมูลแยกต่างหากสำหรับการแจงนับ ไม่เหมือนภาษาอื่นที่มักมี enum เพื่อแสดง โดยทั่วไปใน Go จะทำผ่านการกำหนดประเภทแบบกำหนดเอง + const + iota ด้านล่างเป็นตัวอย่างง่ายๆ

go
type Season uint8

const (
  Spring Season = iota
  Summer
  Autumn
  Winter
)

การแจงนับเหล่านี้其实就是ตัวเลข Go ไม่รองรับการแปลงเป็นสตริงโดยตรง แต่เราสามารถเพิ่มเมธอดให้กับประเภทที่กำหนดเองเพื่อส่งคืนรูปแบบสตริงของมัน ทำให้เป็นอินเทอร์เฟซ Stringer

go
func (s Season) String() string {
  switch s {
  case Spring:
    return "spring"
  case Summer:
    return "summer"
  case Autumn:
    return "autumn"
  case Winter:
    return "winter"
  }
  return ""
}

เช่นนี้ก็เป็นการดำเนินการแจงนับอย่างง่ายแล้ว คุณยังสามารถใช้เครื่องมือทางการ Stringer เพื่อสร้างการแจงนับโดยอัตโนมัติ

แต่มีข้อเสียดังนี้

  • ไม่ปลอดภัยด้านประเภท เพราะ Season เป็นประเภทที่กำหนดเอง สามารถบังคับแปลงประเภทเป็นตัวเลขอื่นเป็นประเภทนี้ได้

    go
    Season(6)
  • ยุ่งยาก ต้องดำเนินการรูปแบบสตริงด้วยตนเอง

  • ความสามารถในการแสดงออกอ่อนแอ เพราะ const รองรับเฉพาะประเภทข้อมูลพื้นฐาน ดังนั้นค่าการแจงนับเหล่านี้สามารถใช้สตริงและตัวเลขเพื่อแสดงได้เท่านั้น

ทำไมไม่รองรับการแจงนับในระดับภาษานี้เป็นสิ่งที่ผู้เขียนไม่เข้าใจอย่างมาก ฉันคิดว่าสิ่งนี้绝对是ประโยชน์มากกว่าโทษ

Golang by www.golangdev.cn edit