Skip to main content

Basic Syntax

Golang 

ไฟล์ Go ประกอบด้วยส่วนต่างๆ ต่อไปนี้:

ประกาศแพ็คเกจ1. การประกาศแพ็คเกจ
แพ็คเกจนำเข้า2. การนำเข้าแพ็คเกจ (import)
3. ฟังก์ชั่น
4. คำสั่งและการแสดงออก

เช่น

package main
import ("fmt")

func main() {
  fmt.Println("Hello GDSC!")
}

Package

Package คือที่เก็บฟังก์ชัน หนึ่งแพ็คเกจสามารถมีไฟล์จำนวนมากที่คุณสามารถตั้งชื่อได้อย่างอิสระซึ่งหนึ่งแพ็คเกจสามารถเก็บได้หลายไฟล์ และสามารถตั้งชื่อไฟล์ได้อย่างอิสระ

Import

Import คือนำเข้าคือการนำเข้า Package จากข้างนอกเข้ามาใช้ในจากข้างนอกเข้ามาใช้ในไฟล์ file goGo ที่เราเขียนอยู่

Example:

import "fmt" --------------------------------> fmt is the name of a package
import "os" ---------------------------------> os is the name of a package
import "github.com/gopherguides/greet" ------> the underlined partthis is the path of the package

Import เรียกใช้ได้สามารถเรียกใช้ได้ 2 แบบ คือ

    Direct Import กับ
    - Single
    - Multiple one-by-one Grouped Import

    Example:

    // Direct import:
    
    // Single:
    import "fmt"
    
    // Multiple one-by-one:
    import "fmt"
    import "math"
    
    // Grouped import:
    import(
        "fmt"
        "math"
    )

    Variables

    Go เป็นภาษาที่ประกาศชนิดของตัวแปรไว้อย่างชัดเจน (Static-Type Language) หมายความว่าคุณต้องประกาศชนิดตัวแปรเมื่อคุณประกาศตัวแปร และไม่สามารถเปลี่ยนแปลงชนิดได้อีก จุดนี้ทำให้ Golang ทำงานได้รวดเร็ว เนื่องจาก compiler ไม่จำเป็นต้องระบุชนิดตัวแปรในขณะ runtime 

    package main
    
    import "fmt"
    
    const globalConstant = 2.72
    const ExportedGlobalConstant = 3.14
    
    func main() {
      var first string
      first = "This is first string"
      
      var second = "This is second string"
      
      third := "This is third string"
      
      fmt.Println(first, second, third)
    }

    การประกาศตัวแปร มี สาม3 วิธี ในการประกาศตัวแปร จากตัวอย่างข้างต้นดังนี้

    แบบแรก- คือfirst การประกาศโดยระบุชนิดตัวแปรให้กับตัวแปรด้วยตนเองการประกาศโดยระบุชนิดตัวแปรด้วยตนเอง

    แบบที่สองและสาม- second และ third คือ การประกาศแบบไม่ระบุชนิดตัวแปรด้วยตนเอง แต่ใช้คำสั่งหลังเครื่องหมายเท่ากับกำหนดชนิดตัวแปรแทน

    แบบที่สาม- third จะต้องมีเครื่องหมาย colon (:) เพื่อประกาศตัวแปร หากไม่มีเครื่องหมายทวิภาค compiler จะส่ง error หากคุณยังไม่เคยประกาศตัวแปรมาก่อน


    Variables type
    package main
    
    import "fmt"
    
    func main() {
      a := 1    // var a int
      b := 3.14 // var b float
      c := "hi" // var c string
      d := true // var d bool
      fmt.Println(a, b, c, d)
    
      e := []int{1, 2, 3} // slice
      e = append(e, 4)
      fmt.Println(e, len(e), e[0], e[1:3], e[1:], e[:2])
      
      f := make(map[string]int) // map
      f["one"] = 1
      f["two"] = 2
      fmt.Println(f, len(f), f["one"], f["three"])
    }

    LikeGolang otherก็เหมือนกับภาษาอื่นๆ languages,ที่มีชนิดของตัวแปรเป็น Go has int, float, string,string andและ boolean asซึ่งเป็น primitive types.data types


    Struct

    ตัวแปรชนิดต่อไปคือStruct "struct"คือชนิดของข้อมูลอีกรูปแบบหนึ่ง อนุญาตให้โปรแกรมเมอร์กำหนดชนิดตัวแปรข้อมูลใหม่ที่มีชนิดตัวแปรข้อมูลอื่นซึ่งมีความคล้ายกับ Object โดยผู้เขียนสามารถใส่ข้อมูล (เรียกว่าฟิลด์)field) ในตัวมันเองเข้าไป และกำหนดชนิดของ field นั้น ๆ ได้

    แต่ละฟิลด์สามารถส่งออกได้โดยใช้กฎเดียวกันกับตัวแปรส่วนกลางซึ่งใช้อักษรตัวแรกของฟิลด์เป็นตัวพิมพ์ใหญ่แต่ละ หมายความว่าจากตัวอย่างฟิลด์ชื่อรหัสและอายุสามารถเข้าถึงได้โดยแพ็คเกจอื่นfield สามารถส่งออกได้โดยใช้กฎเดียวกันกับตัวแปรส่วนกลาง คือการใช้อักษรตัวแรกของฟิลด์เป็นตัวพิมพ์ใหญ่ ซึ่งหมายความว่าจากตัวอย่างด้านล่าง filed Name และ Age สามารถเข้าถึงได้โดยแพ็คเกจอื่น ๆ ในขณะที่ isAdmin ไม่สามารถเข้าถึงได้ ฟิลด์สามารถกำหนด

    แท็กField บอกข้อมูลเกี่ยวกับสามารถกำหนดแท็กเพื่อบอกข้อมูลของ field นั้นๆ เช่น (`json:"name"`) เป็นข้อมูลเมตาสำหรับไลบรารีบางไลบรารีเป็นข้อมูล meta (ข้อมูลที่ใช้อธิบายรายละเอียดของข้อมูล) สำหรับ library บาง library เช่น  JSON libraries (https://golang.org/pkg/encoding/json/) ที่ใช้ "แท็ก" เพื่อแมปเพื่อเปลี่ยนจาก Gomap ฟิลด์โครงสร้างและฟิลด์ไปเป็น JSON หรือ จาก JSON เป็น map

    package main
    
    import "fmt"
    
    type Person struct{
      Name    string `json:"name"`
      Age     int    `json:"age"`
      isAdmin bool
    }
    
    func main() {
      p := Person{
        Name:    "Mike",
        Age:     16,
        isAdmin: false,
      }
      fmt.Println(p, p.Name, p.Age, p.isAdmin)
    }
    
    Type Conversion
    package main
    
    import (
      "fmt"
      "strconv"
      "reflect"
    )
    
    func main() {
      a := 3.14
      b := int(a)
      fmt.Println(b, reflect.TypeOf(b))
      
      c := "12.34"
      d, _ := strconv.ParseFloat(c, 64)
      fmt.Println(d, reflect.TypeOf(d))
      
      e := false
      f := fmt.Sprint(e)
      fmt.Println(f, reflect.TypeOf(f))
    }


    Control Flow Statements

    Conditions
    package main
    
    import "fmt"
    
    func main() {
      // if, else
      a := 5
      if a > 3 {
        a = a - 3
      } else if a == 3 {
        a = 0
      } else {
        a = a + 3
      }
      fmt.Println(a)
      
      // switch, case
      b := "NO"
      switch b {
      case "YES":
        b = "Y"
      case "NO":
        b = "N"
      default:
        b = "X"
      }
      fmt.Println(b)
    }
    Loop
    package main
    
    import "fmt"
    
    func main() {
      // for
      c := 3
      for i := 0; i < c; i++ {
        fmt.Print(i, " ")
      }
      fmt.Println()
      
      // replace while with for
      for c > 0 {
        fmt.Print(c, " ")
        c--
      }
      fmt.Println()
    
      // for with range
      d := []int{0, 1, 1, 2, 3, 5, 8}
      for _, i := range d {
        fmt.Print(i, " ")
      }
      fmt.Println()
    }
    
    Defer

    คำสั่ง "defer" เป็นคำสั่งพิเศษใน Go คุณสามารถเรียกใช้ฟังก์ชันใด ๆ หลังจากคำสั่งเลื่อนหลังจากคำสั่งเลื่อนผ่านไป ฟังก์ชั่นจะถูกเก็บไว้ในสแต็กและจะถูกเรียกใช้หลังจากที่ฟังก์ชันผู้เรียกกลับมาฟังก์ชั่นจะถูกเก็บไว้ใน stack และจะถูกเรียกใช้หลังจากที่ฟังก์ชัน return ดังที่คุณเห็นในตัวอย่าง มีการกลับลำดับของการเรียกใช้ฟังก์ชัน

    package main
    
    import "fmt"
    
    func main() {
      f()
    }
    
    func f() (int, error) {
      defer fmt.Println("DEFER 1")
      defer fmt.Println("DEFER 2")
      defer fmt.Println("DEFER 3")
      fmt.Println("BODY")
      return fmt.Println("RETURN")
    }

    Functions

    Function components

    image.png

    1. Name: ชื่อควรจะเป็นชื่อของฟังก์ชัน แบบควรตั้งเป็นแบบ camelCase / CamelCase.
    2. Arguments: ฟังก์ชันสามารถรับฟังก์ชันสามารถรับหรือไม่รับ arguments เป็นศูนย์หรือมากกว่าได้ก็ได้ สำหรับ arguments ที่อยู่ติดกันตั้งแต่ 2 รายการขึ้นไปที่มีชนิดตัวแปรเดียวกัน คุณสามารถกำหนดชนิดตัวแปรที่ด้านหลังของargumentsสุดท้ายได้สามารถกำหนดชนิดตัวแปรที่ด้านหลังของ argument สุดท้ายได้ (เช่น "String" ในตัวอย่าง)
    3. Return Types: ฟังก์ชันสามารถคืนค่าเป็นศูนย์หรือมากกว่าได้ฟังก์ชันสามารถคืนค่าหรือไม่ก็ได้ หากส่งคืนค่ามากกว่าหนึ่งค่า คุณต้องใส่วงเล็บปิดจะต้องใส่ชนิดของค่าที่จะคืนกลับไปทั้งหมดในวงเล็บ
    4. Body: การทำงานของฟังชั่นเราการทำงานของฟังก์ชัน
    Name Return Values

    เราสามารถเซ็ต ชื่อตัวแปรที่เราจะเราสามารถตั้งชื่อตัวแปรที่เราจะ return ค่าออกไปได้ โดยที่ไม่ต้องใส่ตัวแปรนั้นไว้ line เดียวกับโดยที่ไม่ต้องใส่ตัวแปรนั้นไว้ในบรรทัดเดียวกับ return

    Example:

    package main
    
    import "fmt"
    
    func main() {
      fmt.Println(threeTimes("Thank You GDSC"))
    }
    
    func threeTimes(msg string) (tMsg string) {
      tMsg = msg + ", " + msg + ", " + msg
      return
    }
    Exported / Unexported Functions

    จากตัวอย่างด้านล่างจะเห็นว่า Sum เป็น exported function เพราะว่าชื่อฟังก์ชันตัวแรกเป็นตัวพิมพ์ใหญ่ แต่ factorial เป็น unexported function

    package main
    
    import "fmt"
    
    func main() {
      s := Sum(10)
      f := factorial(10)
      fmt.Println(s, f)
    }
    
    func Sum(n int) int { // exported function
      sum := 0
      for i := 1; i <= n; i++ {
         sum += i
      }
      return sum
    }
    
    func factorial(n int) int { // unexported function
      fac := 1
      for i := 1; i <= n; i++ {
        fac *= 1
      }
      return fac
    }
    Anonymous Functions

    คือฟังก์ชันที่ไม่มีชื่อ และถูกเรียกใช้เลยผ่านการประกาศตัวแปร

    package main
    
    import "fmt"
    
    func main() {
      a := 1
      b := 1
      c := func(x int) int {
        b *= 2
        return x * 2
      }(a)
      fmt.Println(a, b, c)
    }
    
    func mainAnother() {
      myFunc := func(x int) int {
        return x * x
      }
      fmt.Println(myFunc(2), myFunc(3))
    }
    
    Blank Identifiers (_)

    คือตัวแปรที่ไม่ถูกนำมาใช้ และค่าของ blank identifier จะไม่ถูกอ่าน

    ประโยชน์ของ blank identifier คือ ถ้าประกาศตัวแปรมาหลายตัว แต่ไม่ได้ถูกใช้ครบทุกตัวจะ error ทำให้มีการใช้ blank identifier แทน เพื่อให้ compiler มองข้ามตัวแปรนั้นที่ไม่ได้ถูกนำมาใช้

    package main
    
    import "fmt"
    
    func main() {
      x, _ := evenOnly(10)
      fmt.Println(x)
    }
    
    func evenOnly(n int) (int, error) {
      if n%2 == 0 {
        return n / 2, nil
      }
      return 0, fmt.Errorf("not even")
    }