Skip to content
Home » [NEW] เรียนรู้การใช้ภาษา Go ใน 15 นาที | semicolon คือ – NATAVIGUIDES

[NEW] เรียนรู้การใช้ภาษา Go ใน 15 นาที | semicolon คือ – NATAVIGUIDES

semicolon คือ: นี่คือโพสต์ที่เกี่ยวข้องกับหัวข้อนี้

Go เป็นอีกหนึ่งภาษาโปรแกรมที่ป็อบปูล่าสุดๆ เนื้อหอมน่าตามล่ายิ่งกว่าเจ๊ปูน้ำในหูไม่เท่ากันซะอีก

ผลสำรวจจากสวนสัตว์ดุสิตโพลล์พบว่า ส่วนใหญ่คนเขียน Go มักมาจากประชากรโปรแกรมเมอร์ที่เขียนโปรแกรมภาษาใดภาษาหนึ่งเป็นอยู่แล้ว

เพราะภาษาส่วนใหญ่มักมีหลายสิ่งเหมือนกัน จะให้โปรแกรมเมอร์ไปเริ่มภาษาใหม่ด้วยการนั่งอ่านวิธีประกาศตัวแปร ความหมายของ character หรือรู้จักว่า if statement และ for loop ต่างกันยังไง โลกนี้คงตายด้านน่าดู คิดแล้วขอบินไปเปิดหูเปิดตาที่ดูไบบ้างจะดีกว่า

เราเข้าใจคุณ! ชุดบทความนี้ผมจะแนะนำการโปรแกรมด้วยภาษา Go ในมุมมองของโปรแกรมเมอร์ที่มั่วได้ซักภาษา เราจะไม่มา Intro to Programming 101 แต่เราจะท่องดูไบไปดูซิว่า Go มีอะไรเด่นและเด็ดบ้างจนคุณต้องเผ่นออกนอกประเทศ~

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

โอเค เตรียมถุงกาวในมือให้พร้อม แล้วไปดึงดาวกันกับบทความนี้

Table of Contents

อะไร อะไรก็ Go

อะไรคือการที่ Go คลอดตอนปี 2007?

Go เป็นภาษาที่อุบัติในยุคที่อะไรๆก็ไฮโซ CPU ก็เร็ว และเป็นยุคที่ใครยังใช้ CPU คอร์เดียวถือว่าอยู่หลังเขาหิมาลัยละ

ความที่ Go เกิดทีหลัง จึงซึมซับสิ่งดีๆจากภาษาอื่น และอัปเปหิข้อผิดพลาดทั้งหลายของการโปรแกรมแบบเก่าๆ นั่นรวมถึงไวยากรณ์ยุ่งยากคร่ำครึสมัยพ่อขุนราม การเขมือบหน่วยความจำชนิดอดอยากมาสิบปี (Java ไง, เพื่อนเราเอง) หรือการทำงานแบบ Concurrency ที่ยากราวๆข้อสอบ A-NET

ความเร็วในการพัฒนา

จะเลือกอะไรดี ความเร็วในการพัฒนาหรือความเร็วในการประมวลผล?

แน่นอนว่าสองสิ่งนี้ยากที่จะมาด้วยกัน ภาษา C มีประสิทธิภาพดีกว่าภาษา Ruby แต่กลับแย่กว่าในเชิงของการพัฒนาโปรแกรม มุมกลับคือ Ruby เขียนและบำรุงรักษาโปรแกรมได้ง่ายกว่า C แต่ประสิทธิภาพคือลาก่อย

จะดีกว่าไหม ถ้าจะมีซักภาษาที่ทำให้เราพัฒนาโปรแกรมได้ง่าย ความเร็วก็ดี แม้จะไม่ได้เขียนง่ายเท่า Ruby หรือเร็วเท่า Assembly แต่ก็ดีจนเป็นคนที่ใช่ และพร้อมฝากใจให้เป็นแม่ของลูกเรา

Go คือภาษานั้นครับ ด้วยความที่ Go มีไวยากรณ์ไม่ซับซ้อน library ก็ครบครัน แถมใช้เวลาในการ build ได้สั้นเท่าจู๋มด (ใครเคย build โปรเจคใหญ่ๆของภาษา C จะเข้าใจ) Go จึงช่วยให้ชีวิตการพัฒนาโปรแกรมง่ายขึ้น นอกจากนี้ประสิทธิภาพของ Go ก็ดีเยี่ยม ทำงานได้เร็ว แต่ไม่รู้ว่าเร็วเท่า Shinkansen หรือรถไฟความเลวสูงแถวๆนี้ อันนี้ต้องดูอีกที

Google คือยักษ์

ภาษาที่ดีไม่เพียงเกิดจากไวยากรณ์ที่ดี แต่ต้องมีคอมมูนิตี้ที่ดีด้วย

Go เป็นภาษาที่เกิดจากยักษ์ Google และมีการใช้อย่างแพร่หลายโดย Google Adobe IBM Intel และอื่นๆอีกมาก โปรเจคดังๆหลายตัว เช่น Docker และ Kubernate ก็ใช้ Go แล้วตอนนี้หละ คุณพร้อมจะเปิดใจเลือกใช้ Go หรือยัง?

รู้จักภาษา Go ฉบับคนแปลกหน้า

Go เป็น static language นั่นแปลว่าตัวแปรใดต้องมีการประการชนิดข้อมูล และตัวแปรภาษาจะสามารถตรวจสอบชนิดข้อมูลได้ว่าเรากำหนดถูกต้องหรือไม่ตั้งแต่ช่วงของการคอมไพล์

Go ยังเป็นภาษาประเภท compiled language นั่นคือเราสามารถสั่ง compiler ให้อ่านซอร์สโค้ดแล้วสร้างผลลัพธ์ในรูปของโปรแกรม (Executable File) ที่ทำงานบนแพลตฟอร์มนั้นๆได้เลยโดยไม่ทำงานอยู่บน VM เฉกเช่น JVM ในภาษา Java

ภาษา Go นั้นเหมาะกับงานจำพวก System Programs ไม่ว่าจะสร้าง API Server ก็ได้ ทำ Network Applications ก็ดี หรือจะคูลๆชิคๆไปกับการสร้าง Game Engines ก็ไม่ว่ากัน

สวัสดี Golang

เพื่อให้ Go รู้ว่าจะเริ่มทำงานจากจุดไหน จึงจำเป็นที่เราต้องสร้าง package ชื่อ main พร้อมทั้งประกาศฟังก์ชันชื่อ main เช่นกัน

Go

1

2

package

main

3

4

5

func

main

(

)

{

6

7

}

การโปรแกรมด้วย Go สามารถแยกส่วนโค้ดด้วย package ได้ import จึงเป็นคำสำคัญเพื่อใช้ในการนำเข้า package อื่นมาใช้ในโค้ดเรา

Go

1

package

main

2

3

4

import

"fmt"

5

6

func

main

(

)

{

7

8

fmt

.

Println

(

"Hello, Go"

)

9

}

การ import นั้นไม่จำกัดอยู่เฉพาะไลบรารี่ของ Go เอง เรายังสามารถ import ซอร์สโค้ดจากที่อื่น เช่น Github มาใช้ได้ด้วย เช่น

Go

1

import

"github.com/jinzhu/gorm"

คอมไพเลอร์ของ Go นั้นเป็นคนแก่ขี้บ่น เห็นอะไรไม่ต้องตาเป็นต้องเอะอะโวยวาย หากเรา import บางสิ่งเข้ามาแต่ไม่ได้เรียกใช้ เจ๊ Go ก็จะบ่นดังๆตอนเราคอมไพล์ เช่น

Go

1

package

main

2

3

import

"fmt"

4

5

func

main

{

6

7

}

จากโค้ดข้างต้นพบว่าเรา import แพคเกจ fmt เข้ามา แต่ไม่ได้เรียกใช้งาน เมื่อทำการคอมไพล์ Go ก็จะกริ้วนิดหน่อย ด้วยการบ่นๆดังนี้

Code

1

main.go:3:1: imported and not used: "fmt"

Build Run และ Format

สมมติโครงสร้างโปรเจคภายใต้ชื่อ godubai ของเราเป็นดังนี้

Code

1

-- src

2

-- godubai << โปรเจคเรา

3

-- main.go

เมื่อเราต้องการสร้าง executable file เราสามารถออกคำสั่ง go build ได้ ซึ่งจะได้ผลลัพธ์ตามชื่อโปรเจคคือ godubai นั่นหมายความว่าเราสามารถสั่งโปรแกรมนี้ของเราให้ทำงานได้ด้วยการเรียก ./godubai นั่นเอง

ระหว่างช่วงการพัฒนาโปรแกรม เราคงต้องการสั่งโปรแกรมให้ทำงานเพียงเพื่อต้องการเห็นผลลัพธ์ แต่ไม่ต้องการ executable file ออกมา เราสามารถสั่ง go run main.go แทนได้ ด้วยคำสั่งนี้ซอร์สโค้ดของเราจะถูกอ่าน build และ run โดยไม่มีการสร้างไฟล์ผลลัพธ์ให้เป็นขยะในโฟลเดอร์ของเรา

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

Go

1

2

package

main

3

import

"fmt"

4

func

main

(

)

{

5

fmt

.

Println

(

"Hello, Go"

)

6

}

Go ได้เตรียมเครื่องมือ gofmt เพื่อจัดการฟอร์แมตซอร์สโค้ดของคุณให้เป็นตามมาตรฐาน GO ภายหลังออกคำสั่ง gofmt -w main.go หน้าตาโค้ดเราก็จะเข้าสู่สภาวะเป็นผู้เป็นคน

Go

1

package

main

2

3

import

"fmt"

4

5

func

main

(

)

{

6

fmt

.

Println

(

"Hello, Go"

)

7

}

สำหรับแฟลค -w ที่ใส่เข้าไปใน gofmt เป็นการบอกว่าให้เครื่องมือดังกล่าวช่วยเขียนผลลัพธ์ใหม่ลงไฟล์เดิม แทนที่จะเป็นการส่งผลลัพธ์หลังฟอร์แมตออกหน้าจอนั่นเอง

การใช้ gofmt แม้จะดูง่าย แต่ชีวิตเราจะง่ายกว่านี้หากไม่ต้องมาคอยรัน gofmt ดังนั้นเราจึงควรตั้งค่าให้ gofmt ทำงานทุกครั้งหลังจากเรากดเซฟไฟล์ และทำงานอีกครั้งตอนเราส่งโค้ดขึ้น version control

ไหนๆ gofmt ก็ทำให้ชีวิตเป็นเรื่องง่ายแล้ว จะให้ง่ายกว่านี้อีกหน่อยได้ไหม ด้วยการช่วย import package ให้เราอัตโนมัติซะเลย จากในตัวอย่างพบว่าเรามีการใช้งาน fmt แต่ยังไม่ import package ดังกล่าว

Go

1

package

main

2

3

func

main

(

)

{

4

fmt

.

Println

(

"Hello, Go"

)

5

}

Go ได้เตรียมเครื่องมือชื่อ goimports ให้กับเรา หลังออกคำสั่ง goimports -w main.go แพคเกจไหนที่ยังไม่ได้นำเข้า Go ก็จะ import เข้ามาให้ โปรดสังเกตเราใส่ -w เพื่อบอกให้เครื่องมือดังกล่าวเขียนผลลัพธ์ทับไฟล์เดิม

Go

1

package

main

2

3

import

"fmt"

4

5

func

main

(

)

{

6

fmt

.

Println

(

"Hello, Go"

)

7

}

goimports นั้น นอกจากจะทำการ import package ต่างๆที่เราใช้งานในซอร์สโค้ดเข้ามาให้ มันยังทำการฟอร์แมตโค้ดให้กับเราอัตโนมัติโดยไม่ต้องเรียก gofmt เลยด้วยครับ

ประโยคควบคุมในภาษา Go

ประโยคควบคุมในภาษา Go มีไม่เยอะมาก โดยแต่ละตัวก็จะมีลักษณะงานที่เหมาะสมจำเพาะกับมันไปเลย ไม่เหมือนภาษาอื่นๆที่มีทั้ง while และ for-loop ที่ชวนปวดหัวว่าจะใช้ตัวไหนดี

if statement

Go

1

if

i

%

2

==

0

{

2

3

}

else

{

4

5

}

โปรดสังเกต นอกจาก Go จะไม่ต้องปิดท้าย statement ด้วย semicolon แล้ว ประโยคควบคุมยังไม่ต้องครอบด้วยวงเล็บอีกด้วย

for-loop

Go

1

for

i

:=

1

;

i

<=

10

;

i

++

{

2

fmt

.

Println

(

i

)

3

}

for-loop ไม่แตกต่างจากภาษาอื่นมากนัก นั่นคือสามารถแบ่งย่อยออกได้เป็นสามส่วนโดยใช้ semicolon เป็นตัวแบ่ง ส่วนแรกคือการตั้งค่าเริ่มต้น ส่วนถัดมาเป็นเงื่อนไข และส่วนสุดท้ายคือการทำงานหลังจบรอบ

switch

Go

1

switch

i

{

2

case

0

:

fmt

.

Println

(

"Zero"

)

3

case

1

:

fmt

.

Println

(

"One"

)

4

case

2

:

fmt

.

Println

(

"Two"

)

5

case

3

:

fmt

.

Println

(

"Three"

)

6

case

4

:

fmt

.

Println

(

"Four"

)

7

case

5

:

fmt

.

Println

(

"Five"

)

8

default

:

fmt

.

Println

(

"Unknown Number"

)

9

}

ตัวแปรและชนิดข้อมูลในภาษา Go

โดยหลักแล้วเราสามารถประกาศตัวแปรในภาษา Go ได้สองวิธีด้วยกัน

Manual Type Declaration

วิธีการนี้คือการประกาศตัวแปรพร้อมระบุชนิดข้อมูล

Go

1

var

<

ชื่อตัวแปร

>

<

ชนิดข้อมูล

>

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

Go

1

var

message

string

2

message

=

"Hello, Go"

คำถามครับ สมมติเราประกาศตัวแปรขึ้นมา แต่ยังไม่ได้กำหนดค่าให้มันหละ เช่นนี้ค่าของตัวแปรดังกล่าวจะเป็นอะไร?

Zero Values เป็นคำเรียกเก๋ๆสำหรับค่า “default value” ในกรณีที่เราประกาศตัวแปรขึ้นมาแต่ไม่ได้กำหนดค่าให้กับมัน ตัวอย่างเช่น

TypeZero Valueboolfalseint0float0.0string””functionnil

เพราะฉะนั้น หากเราประกาศ var message string ขึ้นมาลอยๆ ตอนนี้คงตอบได้แล้วซิครับว่า message นั้นมีค่าเป็น “” นั่นเอง

Type Inference

กรณีที่เราต้องการประกาศตัวแปรพร้อมทั้งกำหนดค่าพร้อมกันในคราเดียว เราสามารถใช้ไวยากรณ์แบบนี้ได้ครับ

Go

1

<

ชื่อตัวแปร

>

:=

<

ค่า

>

2

3

4

message

:=

"Hello, Go"

การประกาศตัวแปรพร้อมระบุค่าด้วยการใช้ := Go จะดูว่าฝั่งขวานั้นมีชนิดข้อมูลเป็นอะไร เพื่อนำไปอนุมานว่าตัวแปรดังกล่าวควรเป็นชนิดข้อมูลอะไร เราจึงเรียกวิธีกำหนดค่าแบบนี้ว่า Type Inference

Arrays และ Slices ในภาษา Go

อาร์เรย์ในภาษา Go ก็มีวิธีประกาศและใช้ไม่ต่างอะไรจากภาษาอื่นมากนัก

Go

1

2

var

names

[

3

]

string

3

4

names

[

0

]

=

"Somchai"

5

names

[

1

]

=

"Somsree"

6

names

[

2

]

=

"Somset

หรือถ้าคุณเป็นสายย่อ โค้ดต่อไปนี้จะดูกรุบกริบ

Go

1

names

:=

[

3

]

string

{

"Somchai"

,

"Somsree"

,

"Somset"

}

อาร์เรย์อาจไม่ยืดหยุ่นเพียงพอสำหรับเรา การประกาศอาร์เรย์เราต้องระบุขนาดของมัน แต่การใช้งานจริงของเราเราอาจต้องการยืดและหดขนาดได้อย่างอิสระ Slices จึงเข้ามาตอบโจทย์ตรงนี้แทน Arrays

Go

1

2

3

var

names

[

]

string

4

5

6

names

=

append

(

names

,

"Somchai"

)

7

names

=

append

(

names

,

"Somsree"

)

8

names

=

append

(

names

,

"Somset"

)

สำหรับสายย่อ slices ก็มีวิธีประกาศเช่นเดียวกับ arrays เพียงแต่ไม่ต้องระบุจำนวน

Go

1

names

:=

[

]

string

{

"Somchai"

,

"Somsree"

,

"Somset"

}

arrays และ slices ยังสามารถใช้ for เพื่อวนลูปได้ผ่าน range

Go

1

names

:=

[

3

]

string

{

"Somchai"

,

"Somsree"

,

"Somset"

}

2

3

for

index

,

name

:=

range

names

{

4

fmt

.

Println

(

index

,

name

)

5

}

6

7

8

9

10

ฟังก์ชันในภาษา Go

ฟังก์ชันในภาษา Go ก็เป็นปกติทั่วไปตามแบบฉบับภาษาตระกูลมี Type ต่างกันนิดหน่อยตรงที่ชื่อตัวแปรจะมาก่อนชนิดข้อมูล เช่น

Go

1

package

main

2

3

import

(

4

"fmt"

5

)

6

7

func

main

(

)

{

8

printFullName

(

"Babel"

,

"Coder"

)

9

}

10

11

12

func

printFullName

(

firstName

string

,

lastName

string

)

{

13

fmt

.

Println

(

firstName

+

" "

+

lastName

)

14

}

ในกรณีที่มีการคืนค่ากลับจากฟังก์ชัน เราต้องระบุชนิดข้อมูลของค่าที่จะคืนออกไปด้วย

Go

1

2

func

getMessage

(

)

string

{

3

4

}

ฟังก์ชันในภาษา Go สามารถคืนค่าได้มากกว่าหนึ่งค่า และเป็นธรรมเนียมปฏิบัติที่เรามักจะคืนค่า error เพื่อบ่งบอกว่าการทำงานของฟังก์ชันมีปัญหาหรือไม่ออกมาด้วย

Go

1

package

main

2

3

import

(

4

"errors"

5

"fmt"

6

)

7

8

func

main

(

)

{

9

10

result

,

err

:=

divide

(

5

,

3

)

11

12

13

if

err

!=

nil

{

14

os

.

Exit

(

1

)

15

}

16

17

fmt

.

Println

(

result

)

18

}

19

20

21

func

divide

(

dividend

float32

,

divisor

float32

)

(

float32

,

error

)

{

22

if

divisor

==

0.0

{

23

err

:=

errors

.

New

(

"Division by zero!"

)

24

return

0.0

,

err

25

}

26

27

return

dividend

/

divisor

,

nil

28

}

นิยามโครงสร้างข้อมูลด้วย Structs

แม้ภาษา Go จะไม่มีคลาส แต่เรามี structs ที่สามารถนิยามโครงสร้างของข้อมูลขึ้นมาเองได้

Go

1

type

human

struct

{

2

name

string

3

age

int

4

}

หลังจากที่เรานิยามโครงสร้างข้อมูลภายใต้ชื่อ Human เราก็สามารถสร้างข้อมูลเหล่านี้พร้อมตั้งค่าให้กับมันได้ ดังนี้

Go

1

somchai

:=

human

{

name

:

"Somchai"

,

age

:

23

}

2

somsree

:=

human

{

name

:

"Somsree"

,

age

:

32

}

เมื่อ structs เป็นตัวแทนของโครงสร้างข้อมูลที่เรานิยามขึ้นมา เราจึงสามารถนิยามพฤติกรรมที่สัมพันธ์กับ structs นี้ได้

Go

1

type

human

struct

{

2

name

string

3

age

int

4

}

5

6

7

8

func

(

h human

)

printInfo

(

)

{

9

fmt

.

Println

(

h

.

name

,

h

.

age

)

10

}

11

12

func

main

(

)

{

13

somchai

:=

human

{

name

:

"Somchai"

,

age

:

23

}

14

somchai

.

printInfo

(

)

15

}

พอยเตอร์ในภาษา Go

สมมติเราต้องการสร้างฟังก์ชันใหม่ชื่อ setIsAdult ทำหน้าที่ในการตรวจสอบอายุของคนนั้นๆ หากอายุเกิน 18 ปีจะถือว่าเป็นผู้ใหญ่แล้ว

Go

1

package

main

2

3

import

"fmt"

4

5

type

human

struct

{

6

name

string

7

age

int

8

isAdult

bool

9

}

10

11

12

13

14

func

setAdult

(

h human

)

{

15

h

.

isAdult

=

h

.

age

>=

18

16

}

17

18

func

main

(

)

{

19

somchai

:=

human

{

name

:

"Somchai"

,

age

:

23

}

20

setAdult

(

somchai

)

21

fmt

.

Println

(

somchai

)

22

}

เมื่อผ่าน somchai เข้าไปยังฟังก์ชัน setAdult ปรากฎว่าค่า isAdult ของ somchai ไม่ถูกเซ็ตเป็น true ทำไมจึงเป็นเช่นนั้น?

ภาษา Go ส่งค่าเข้าฟังก์ชันแบบ Pass by Value ความหมายคือมันจะทำการก็อบปี้ข้อมูลต้นทางมาไว้กับฟังก์ชันอีกชุด ดังนั้น somchai และตัวแปร h สำหรับฟังก์ชันจึงเป็นคนละตัว การแก้ไขค่า h.isAdult จึงไม่ใช่การแก้ไข somchai.isAdult นั่นเอง

วิธีแก้คือเราต้องส่ง Reference ของ somchai ไปให้กับฟังก์ชัน โดยที่ฟังก์ชันเมื่อได้รับ reference มาแล้วต้องทำการ dereference หรือถอดเอาค่าที่แท้จริงออกมา

Go

1

package

main

2

3

import

"fmt"

4

5

type

human

struct

{

6

name

string

7

age

int

8

isAdult

bool

9

}

10

11

12

func

setAdult

(

h

*

human

)

{

13

h

.

isAdult

=

h

.

age

>=

18

14

}

15

16

func

main

(

)

{

17

somchai

:=

human

{

name

:

"Somchai"

,

age

:

23

}

18

19

setAdult

(

&

somchai

)

20

fmt

.

Println

(

somchai

)

21

}

ภาษา Go ไม่มีการสืบทอดนะจ๊ะ

การสืบทอด (inheritance) เป็นหนึ่งในหลักการที่โปรแกรมเมอร์มักใช้กันผิดๆ ลองดูการสืบทอดที่เราทำกันผิดๆในภาษาอื่นๆกัน

สมมติว่าในสำนักงานเรามีอุปกรณ์มากมาย ส่วนใหญ่เข้าถึงได้จาก IP เราจึงสร้างคลาส Devise แทนอุปกรณ์ของเรา

TypeScript

1

class

Devise

{

2

ip

:

string

3

location

:

string

4

}

เนื่องจากออฟฟิตเรามีเครื่องพิมพ์ จึงเพิ่ม printer ให้สืบทอดจาก Devise เพราะเป็นอุปกรณ์เหมือนกัน

TypeScript

1

class

Device

{

2

ip

:

string

3

location

:

string

4

}

5

6

class

Printer

extends

Device

{

7

print

(

)

{

8

9

}

10

}

ฝ่ายขายเห็นฮาร์ดดิสก์ลดราคา เลยจัดมาซักสองสามตัว

TypeScript

1

class

Device

{

2

ip

:

string

3

location

:

string

4

}

5

6

class

Harddisk

extends

Device

{

7

store

(

)

{

8

9

}

10

}

ทว่า Harddisk ไม่ได้ติดต่อผ่าน IP แต่เราดันเก็บ IP ไว้กับ Device เป็นผลให้ Harddisk มีฟิลด์ IP ลอยหน้าลอยตาเล่นๆ โดยไม่ได้ใช้งาน

Go นั้นชอบให้เราประกอบร่างจากชิ้นส่วนเล็กๆ ให้เป็นชิ้นส่วนใหญ่ ตามหลักการ Composition over Inheritance มากกว่า เราจึงไม่เห็นไวยากรณ์ของการสืบทอดในภาษา Go

สำหรับเพื่อนๆที่สนใจสามารถอ่านเพิ่มเติมได้จาก รู้จัก Composition over Inheritance หลักการออกแบบคลาสให้ยืดหยุ่น

Interfaces และ Duck Typing

Go ก็มี Interface เหมือนภาษา Java และ C# เพียงแต่ Go ไม่ต้อง implements Interface แบบเดียวกับภาษาเหล่านั้น

Go

1

package

main

2

3

import

"fmt"

4

5

type

human

struct

{

6

name

string

7

age

int

8

}

9

10

type

parrot

struct

{

11

name

string

12

age

int

13

}

14

15

type

talker

interface

{

16

talk

(

)

17

}

18

19

func

(

h human

)

talk

(

)

{

20

fmt

.

Println

(

"Human - I'm talking."

)

21

}

22

23

func

(

p parrot

)

talk

(

)

{

24

fmt

.

Println

(

"Parrot - I'm talking."

)

25

}

26

27

func

main

(

)

{

28

talkers

:=

[

2

]

talker

{

29

human

{

name

:

"Somchai"

,

age

:

23

}

,

30

parrot

{

name

:

"Dum"

,

age

:

2

}

,

31

}

32

33

for

_

,

talker

:=

range

talkers

{

34

talker

.

talk

(

)

35

}

36

37

38

39

40

}

จากตัวอย่างพบว่าทั้งนกแก้วและคนต่างเป็นนักพูด เราจึงประกาศ interface ชื่อ talker ขึ้นมา การที่จะทำให้ Go รู้ว่าคนและนกแก้วเป็นนักพูดนั้น เราไม่ต้อง implements interface แบบภาษาอื่น Go ถือหลักการของ Duck Typing นั่นคือ ถ้าคุณร้องก๊าบๆและเดินเหมือนเป็ด คุณก็คือเป็ด หาก struct คุณมีเมธอด talk คุณก็คือ taker นั่นเอง!

Concurrency และ Parallelism

หนึ่งในจุดเด่นของภาษา Go คือการโปรแกรมเพื่อทำ Concurrency ที่ง่ายกว่าและมีประสิทธิภาพมากกว่าด้วย Goroutines แต่ก่อนที่เราจะไปทำความรู้จักกับฟีเจอร์นี้ เราต้องแยกแยะสองคำที่แตกต่างคือ Concurrency และ Parallelism ออกจากกันเสียก่อน

เราต้องการสร้างระบบค้นหารูปภาพด้วยชื่อจากโฟลเดอร์ต่างๆในคอมพิวเตอร์ สมมติว่ามีสามโฟลเดอร์คือ Document Image และ Library

โดยทั่วไปการค้นหารูปภาพด้วยโค้ดปกติของเรา เราจะทำการค้นหาไปทีละโฟลเดอร์ เช่น ไล่ตั้งแต่ Document เมื่อค้นหาเสร็จ จึงไปค้นหาที่โฟลเดอร์ Image ต่อ เมื่อเสร็จสิ้นจึงค้นหาที่โฟลเดอร์ Library เป็นรายการสุดท้าย

Go

1

func

search

(

keyword

string

)

{

2

folders

:=

[

3

]

string

{

"Document"

,

"Image"

,

"Library"

}

3

4

5

for

_

,

folder

:=

range

folders

{

6

7

}

8

}

9

10

func

main

(

)

{

11

search

(

"dog"

)

12

}

จากโค้ดข้างต้นเราพบว่า โปรแกรมของเราจะไม่สามารถค้นหารูปภาพจากโฟลเดอร์อื่นได้เลย หากการค้นหาในโฟลเดอร์ก่อนหน้ายังไม่เสร็จสิ้น

เราทราบว่าการค้นหารูปภาพจากโฟลเดอร์ต่างๆเป็นอิสระต่อกัน การค้นหารูปภาพใน Image ไม่เกี่ยวอะไรกับการค้นหารูปภาพใน Document หรือ Library เลย ด้วยเหตุนี้เราจึงแบ่งการทำงานของโปรแกรมเราออกเป็นสามส่วน คือ ค้นหา Document ค้นหา Image และ ค้นหา Library อย่างเป็นอิสระต่อกัน เราเรียกการโปรแกรมเพื่อแยกงานให้สามารถทำงานได้อย่างเป็นอิสระจากกันนี้ว่า Concurrency

เมื่อทุกส่วนของโปรแกรมเป็นอิสระต่อกัน เราจะเริ่มทำส่วนไหนก่อนก็ไม่ใช่ปัญหา จะเริ่มค้นหาที่ Document ก่อน หรือจะเริ่มค้นหาที่ Image ก่อน แบบไหนก็ผลลัพธ์ไม่แตกต่าง

นี่คือยุค 2017 ที่ใครๆก็ใช้ CPU หลายคอร์ละนะ เมื่องานแต่ละชิ้นเป็นอิสระต่อกัน ก็แจกจ่ายงานแต่ละส่วนให้ CPU แต่ละคอร์ทำงานไปแบบอิสระต่อกันซะ การทำงานแบบขนานเช่นนี้เราเรียกว่า Parallelism

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

Goroutines

เราสามารถสร้างการทำงานแบบ Concurrency ได้ด้วยการใช้ Goroutines เพียงแค่เติม go เข้าไปข้างหน้าฟังก์ชัน ทุกอย่างก็จะสดชื่น

Go

1

func

searchFromFolder

(

keyword

string

,

folder

string

)

{

2

3

}

4

5

func

search

(

keyword

string

)

{

6

folders

:=

[

3

]

string

{

"Document"

,

"Image"

,

"Library"

}

7

8

for

_

,

folder

:=

range

folders

{

9

10

go

searchFromFolder

(

keyword

,

folder

)

11

}

12

}

13

14

func

main

(

)

{

15

search

(

"dog"

)

16

}

แน่นอนว่าการทำงานแบบ Concurrency ด้วย Goroutines นี้หากเราทำงานบน CPU หลายคอร์ก็จะเปลี่ยนเป็นการทำงานแบบขนานได้

หากใครได้ลองรันโปรแกรมดังกล่าวจะพบว่าโปรแกรมหยุดการทำงานทันที สำหรับภาษา Go เมื่อ main สิ้นสุด การทำงานก็จะสิ้นสุดตาม เราจึงต้องเพิ่มอะไรบางอย่างเพื่อบอกให้ Go คอยการทำงานของ Goroutines ให้เสร็จสิ้นเสียก่อน สิ่งนั้นก็คือ WaitGroup ภายใต้แพคเกจ sync

Go

1

import

"sync"

2

3

func

search

(

keyword

string

)

{

4

var

wg sync

.

WaitGroup

5

6

}

7

8

func

main

(

)

{

9

search

(

"dog"

)

10

}

เพื่อให้ Go ทราบว่าจะต้องรอการทำงานของ Goroutines กี่ตัว เราจึงต้องระบุจำนวนลงไป

Go

1

import

"sync"

2

3

func

search

(

keyword

string

)

{

4

folders

:=

[

3

]

string

{

"Document"

,

"Image"

,

"Library"

}

5

var

wg sync

.

WaitGroup

6

7

wg

.

Add

(

len

(

folders

)

)

8

9

}

10

11

func

main

(

)

{

12

search

(

"dog"

)

13

}

และเพื่อป้องกันไม่ให้ Go หยุดการทำงานไปในทันที เราจึงต้อง Wait จนกว่า Goroutines จะทำงานเสร็จหมด

Go

1

import

"sync"

2

3

func

search

(

keyword

string

)

{

4

folders

:=

[

3

]

string

{

"Document"

,

"Image"

,

"Library"

}

5

var

wg sync

.

WaitGroup

6

wg

.

Add

(

len

(

folders

)

)

7

8

9

wg

.

Wait

(

)

10

}

11

12

func

main

(

)

{

13

search

(

"dog"

)

14

}

คำถามถัดมา Go จะรู้ได้อย่างไรว่า Goroutine ตัวไหนทำงานเสร็จแล้วบ้าง เราจึงต้องสั่ง Done ในแต่ละ routine เพื่อบอกว่าการทำงานของมันเสร็จสิ้นแล้ว

Go

1

import

"sync"

2

3

4

func

searchFromFolder

(

keyword

string

,

folder

string

,

wg

*

sync

.

WaitGroup

)

{

5

6

7

8

wg

.

Done

(

)

9

}

10

11

func

search

(

keyword

string

)

{

12

folders

:=

[

3

]

string

{

"Document"

,

"Image"

,

"Library"

}

13

var

wg sync

.

WaitGroup

14

wg

.

Add

(

len

(

folders

)

)

15

for

_

,

folder

:=

range

folders

{

16

17

go

searchFromFolder

(

keyword

,

folder

,

&

wg

)

18

}

19

wg

.

Wait

(

)

20

}

21

22

func

main

(

)

{

23

search

(

"dog"

)

24

}

เป็นอันจบพิธี~

รู้จัก Package ในภาษา Go

เมื่อโปรแกรมมีขนาดใหญ่ขึ้น เราอาจต้องมีการแยกโค้ดของเราเป็นหลายแพคเกจ

Code

1

-- src

2

-- godubai

3

-- main.go

4

-- search

5

-- main.go

เราอาจสร้างแพคเกจ search ขึ้นมาเพื่อแยกการค้นหาออกจากแพคเกจหลักคือ main

Go

1

func

searchFromFolder

(

keyword

string

,

folder

string

,

wg

*

sync

.

WaitGroup

)

{

2

3

wg

.

Done

(

)

4

}

5

6

func

Run

(

keyword

string

)

{

7

folders

:=

[

3

]

string

{

"Document"

,

"Image"

,

"Library"

}

8

var

wg sync

.

WaitGroup

9

wg

.

Add

(

len

(

folders

)

)

10

for

_

,

folder

:=

range

folders

{

11

go

searchFromFolder

(

keyword

,

folder

,

&

wg

)

12

}

13

wg

.

Wait

(

)

14

}

ส่วนของ main ต้องมีการ import แพคเกจดังกล่าวเข้ามาใช้งาน

Go

1

import

"godubai/search"

2

3

func

main

(

)

{

4

search

.

Run

(

"dog"

)

5

}

หลังจากผ่านโค้ดกันมาเยอะแล้ว เพื่อนๆคงอาจสงสัย เอ๊ะทำไมฟังก์ชันบางตัวก็ขึ้นต้นด้วยตัวเล็ก บางตัวก็ขึ้นต้นด้วยตัวใหญ่?

สำหรับภาษา Go การขึ้นต้นด้วยตัวเล็กใหญ่มีความสำคัญครับ ถ้าตัวแปร ฟังก์ชัน structs หรืออื่นใด ที่ขึ้นต้นด้วยตัวเล็ก สิ่งนั้นจะอ้างอิงถึงได้เฉพาะในแพคเกจตัวเอง หากต้องการให้เข้าถึงได้จากแพคเกจอื่น เราต้องขึ้นต้นสิ่งเหล่านั้นด้วยอักษรตัวใหญ่แทน นี่จึงเป็นเหตุผลที่ว่าทำไม Run ในแพคเกจ search ถึงขึ้นต้นด้วยตัวใหญ่ เพราะมีการเรียกใช้จากแพคเกจอื่นคือ main นั่นเอง

สรุป

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

[NEW] หลักการใช้คอมม่า (Comma) ในภาษาอังกฤษ | semicolon คือ – NATAVIGUIDES

คอมม่า (,) เป็นเครื่องหมายวรรคตอนที่ใช้บ่อยในภาษาอังกฤษ แต่ถึงแม้จะถูกใช้บ่อย หลายๆคนก็ยังคงสับสนอยู่ดี ว่าเราควรใช้คอมม่าตอนไหนและต้องใช้อย่างไรบ้าง

สำหรับคนที่สงสัย ในบทความนี้ ชิววี่ก็ได้เรียบเรียงเนื้อหาการใช้คอมม่าในภาษาอังกฤษ มาให้เพื่อนๆได้เรียนรู้กันได้อย่างง่ายๆแล้ว ถ้าเพื่อนๆพร้อมแล้ว เราไปดูกันเลย

คอมม่าคืออะไร

คอมม่า (comma) เป็นเครื่องหมายวรรคตอนในภาษาอังกฤษ ทำหน้าที่แยกคำ วลี หรือประโยค เพื่อให้ผู้อ่านสามารถอ่านจับใจความได้ง่ายและถูกต้องมากขึ้น

ถ้าเปรียบเทียบคอมม่ากับเครื่องหมายจุด (.) ที่ใช้ปิดท้ายประโยค หรือที่เรียกว่า period เครื่องหมายทั้ง 2 ตัวนี้จะเป็นตัวบอกการเว้นจังหวะในการอ่านและพูดเหมือนกัน แต่เครื่องหมายคอมม่าจะเป็นตัวบอกจังหวะการเว้นที่สั้นกว่า

หลักการใช้คอมม่า

ใครที่มีข้อสงสัยว่าเราต้องใช้คอมม่าในกรณีไหนและต้องใช้ยังไงบ้าง ก็ไปดูหลักการใช้คอมม่าทั้ง 11 ข้อกันเลย

1. ใช้คอมม่าหน้าคำเชื่อมที่เชื่อม independent clause

Independent clause (ประโยคใจความสมบูรณ์) คือประโยคที่มีทั้งประธานและคำกริยา ตัวประโยคจะมีใจความสมบูรณ์ในตัวมันเอง เช่น

I am a student. (ฉันเป็นนักเรียน) – ถือเป็น independent clause เพราะมีทั้งประธานและคำกริยา
Feel good (รู้สึกดี) – ไม่ใช่ independent clause เพราะไม่มีประธาน
Big black cat (แมวสีดำตัวใหญ่) – ไม่ใช่ independent clause เพราะไม่มีคำกริยา

ส่วนคำเชื่อมในที่นี้จะต้องเป็น coordinating conjunction ซึ่งก็คือคำเชื่อมที่ให้น้ำหนักกับ 2 สิ่งที่ถูกเชื่อมเท่าๆกัน โดยอาจใช้เชื่อมคำ วลี หรือประโยคก็ได้ coordinating conjunction มีทั้งหมด 7 ตัวคือ for, and, nor, but, or, yet, so (เมื่อนำอักษรแรกมาต่อกันจะได้เป็น FANBOYS ใช้ช่วยให้ท่องจำได้ง่ายขึ้น)

หากเราเชื่อม independent clause 2 ประโยคด้วย coordinating conjunction เราจะต้องใช้คอมม่าหน้า coordinating conjunction

โครงสร้างการใช้

independent clause + , + coordinating conjunction + independent clause

ตัวอย่างประโยค

He didn’t speak to anyone, and nobody spoke to him.
เขาไม่ได้พูดกับใคร และก็ไม่มีใครพูดกับเขา

I wanted to stay home, but my wife wanted to go shopping.
ฉันอยากอยู่บ้าน แต่ภรรยาของฉันอยากไปช้อปปิ้ง

เราจะไม่ใช้คอมม่า ถ้าข้างหน้าหรือข้างหลัง coordinating conjunction ไม่ใช่ independent clause

She brushed her teeth and washed her face.
เธอแปรงฟันและล้างหน้า
(washed her face ไม่ใช่ independent clause)

I am not a writer but an editor.
ฉันไม่ใช่นักเขียน แต่เป็นบรรณาธิการ
(an editor ไม่ใช่ independent clause)

2. ใช้คอมม่าเมื่อขึ้นต้นประโยคด้วย dependent clause

Dependent clause คือประโยคที่มีใจความไม่สมบูรณ์ เวลาใช้จะต้องใช้ร่วมกับประโยคอื่น ในที่นี้เราจะแบ่งออกเป็น 3 กรณี

1. Participial phrase

เมื่อประโยคขึ้นต้นด้วยวลีจำพวก participial phrase ซึ่งก็คือวลีที่ขึ้นต้นด้วย v. + ing หรือ v. ช่อง 3 เราจะต้องใช้คอมม่าคั่นหลังวลีนั้น

โครงสร้างการใช้

participial phrase + , + ประโยคหลัก

ตัวอย่างประโยค

Being the only son in the family, his family have high hopes for him.
ด้วยการที่เขาเป็นลูกชายคนเดียวในครอบครัว ครอบครัวของเขาจึงตั้งความหวังกับเขาไว้สูง

Bitten by my own dog, I was very disappointed.
การโดนกัดโดยหมาของตัวเองทำให้ฉันรู้สึกผิดหวังมาก

2. Adverbial phrase

แต่ถ้าประโยคขึ้นต้นด้วย adverbial phrase ซึ่งก็คือวลีที่ทำหน้าที่เป็น adverb เราอาจใช้คอมม่าหรือไม่ใช้ก็ได้ (ถ้า adverbial phrase ยาว หรือเราต้องการเน้น adverbial phrase นั้น เราจะนิยมใช้คอมม่า)

ตัวอย่าง adverbial phrase เช่น
At 6 o’clock
After the show
In the middle of Bangkok

โครงสร้างการใช้

adverbial phrase + (,) + ประโยคหลัก

ตัวอย่างประโยค

In 2020 there is a pandemic affecting the world.
ในปี 2020 มีโรคระบาดที่ส่งผลกระทบไปทั่วโลก

When I was six, I lived in Chiang Mai with my mom.
ตอนฉันอายุหกขวบ ฉันอาศัยอยู่ที่เชียงใหม่กับแม่ของฉัน

3. Sentence adverb

ถ้าประโยคขึ้นต้นด้วย sentence adverb ซึ่งก็คือคำจำพวก adverb ที่ทำหน้าที่ขยายทั้งประโยค เราจะใช้คอมม่าคั่นหลัง sentence adverb นั้น

โครงสร้างการใช้

sentence adverb + , + ประโยคหลัก

ตัวอย่างประโยค

Honestly, I am not angry.
ตรงๆเลยนะ ฉันไม่ได้โกรธ

Clearly, this plan isn’t working.
เห็นได้ชัดว่าแผนนี้ใช้ไม่ได้ผล

3. ใช้คอมม่าคั่นวลีหรือคำกลางประโยคที่ทำหน้าที่ให้ข้อมูลเพิ่มเติม

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

โครงสร้างการใช้

ประโยคส่วนที่ 1 + , + วลี/คำที่ทำหน้าที่ให้ข้อมูลเพิ่มเติม + , + ประโยคส่วนที่ 2

ตัวอย่างประโยค

Tim, unlike Joe, is very polite.
ทิมเป็นคนสุภาพมาก ไม่เหมือนกับโจ

King Crab restaurant, which Anne recommended, is fantastic.
ร้านอาหารคิงแครบที่แอนแนะนำนั้นดีมาก

แต่ถ้าวลีหรือคำนั้นจำเป็นสำหรับประโยค ถ้าตัดออกแล้วใจความเปลี่ยน เราก็จะไม่ใช้คอมม่า

People who exercise regularly tend to be more happy.
คนที่ออกกำลังกายสม่ำเสมอมักจะมีความสุขมากกว่า
(ถ้าตัด who exercise regularly ทิ้ง ความหมายจะเปลี่ยนเป็น “คนจะมีความสุขมากกว่า” ซึ่งมีใจความผิดไปจากเดิม)

The restaurant that Anne recommended is fantastic.
ร้านอาหารที่แอนแนะนำนั้นดีมาก
(ถ้าตัด that Anne recommended ทิ้ง ความหมายจะเปลี่ยนเป็น “ร้านอาหารดีมาก” ซึ่งมีใจความผิดไปจากเดิม คือเราจะไม่รู้ว่าหมายถึงร้านไหน)

วลีที่ขึ้นต้นด้วย that มักจะจำเป็นสำหรับประโยค เรามักจะไม่ใช้คอมม่าครอบส่วนนั้น

4. ใช้คอมม่าแยกรายการคำตั้งแต่ 3 รายการขึ้นไป

ถ้าเรามีรายการคำตั้งแต่ 3 รายการขึ้นไป เราจะต้องคั่นแต่ละรายการด้วยคอมม่า ยกเว้นรายการสุดท้าย เราจะคั่นด้วยคอมม่าหรือไม่ก็ได้

โครงสร้างการใช้

รายการหนึ่ง, รายการสอง(,) and รายการสุดท้าย

ตัวอย่างประโยค

He is tall, dark, and handsome.
หรือ He is tall, dark and handsome.
เขาทั้งสูง เข้ม และหล่อ

She needs salt, pepper, and other seasonings at the grocery store.
หรือ She needs salt, pepper and other seasonings at the grocery store.
เธอต้องการเกลือ พริกไทย และเครื่องปรุงอย่างอื่นที่ร้านขายของ

5. ใช้คอมม่าคั่นระหว่าง coordinate adjectives

Coordinate adjectives คือคำคุณศัพท์ที่ขยายคำนามคำเดียวกันและมีความสำคัญเท่าๆกัน สามารถสลับที่กันได้ ตัวอย่างเช่น

เราสามารถใช้ได้ทั้ง long, narrow path
และ narrow, long path
คำว่า long และ narrow ในที่นี้จะถือเป็น coordinate adjectives

เราสามารถใช้ big black bear
แต่ไม่สามารถใช้ black big bear
คำว่า big และ black ไม่ถือเป็น coordinate adjectives (การใช้ adjective ขนาดจะต้องมาก่อนสี)

โครงสร้างการใช้

coordinate adjective 1 + , + coordinate adjective 2 + คำนาม

ตัวอย่างประโยค

The happy, lively cat is playing with the ball.
แมวที่มีความสุขสดใสกำลังเล่นกับลูกบอล

My roommate is a cheerful, kind girl.
รูมเมทของฉันเป็นเด็กผู้หญิงที่ร่าเริงและใจดี

ทั้งนี้ เราสามารถใช้ and เชื่อมระหว่าง coordinate adjectives แทนคอมม่าก็ได้เช่นกัน อย่างเช่น My roommate is a cheerful and kind girl.

6. ใช้คอมม่าคั่นระหว่างคำพูดกับวลีที่กำกับ

ในภาษาอังกฤษ เวลาเราเขียนประโยคที่เป็นคำพูด เราจะใช้เครื่องหมาย “-” ครอบประโยคคำพูดนั้น อย่างเช่น Anne said, “I feel sick.” ซึ่งแปลว่า แอนพูดว่า “ฉันรู้สึกป่วย”

สังเกตว่า เราจะใช้คอมม่าคั่นระหว่างวลีที่เข้ามากำกับ ซึ่งก็คือ Anne said และประโยคที่เป็นคำพูด ซึ่งก็คือ “I feel sick.”

ทั้งนี้ วลีที่กำกับนั้นอาจจะอยู่หน้า อยู่กึ่งกลาง หรืออยู่หลังประโยคที่เป็นคำพูดก็ได้

โครงสร้างการใช้

  • วลีกำกับ, “ประโยคคำพูด”
  • “ประโยคคำพูด,” วลีกำกับ, “ประโยคคำพูด”
  • “ประโยคคำพูด,” วลีกำกับ

ตัวอย่างประโยค

He answered, “She is not here.”
เขาตอบ “เธอไม่ได้อยู่ที่นี่”

“I think,” she said, “Joe can help.”
“ฉันคิดว่า” เธอพูด “โจสามารถช่วยได้”

“It is raining,” Tim said.
“ฝนกำลังตก” ทิมพูด

ในกรณีที่วลีกำกับอยู่ข้างหลังประโยคคำพูด ถ้าประโยคคำพูดลงท้ายด้วยเครื่องหมายตกใจ (!) หรือเครื่องหมายคำถาม (?) เราจะไม่ต้องใช้คอมม่า

“Stop playing video game!” mom yelled.
“หยุดเล่นเกมได้แล้ว” แม่ตวาด

“Are you alright?” Ben asked.
“คุณโอเคมั้ย” เบ็นถาม

บางคนอาจสงสัยว่า เราต้องใส่คอมม่าไว้ในหรือนอกเครื่องหมาย “-” ทำไมบางทีเห็นแต่ละที่ใช้ไม่เหมือนกัน

คำตอบก็คือถ้าเป็น American English จะนิยมเอาไว้ข้างใน เช่น “It is raining,” Tim said. แต่ถ้าเป็น British English จะนิยมเอาไว้ข้างนอก เช่น “It is raining”, Tim said.

7. ใช้คอมม่าในการแยกวันที่และสถานที่

ใช้คอมม่าคั่นระหว่างวันและปีเมื่อเราเขียนวันที่ในรูปแบบ เดือน-วันที่-ปี แต่ถ้าเราเขียนในรูปแบบ วันที่-เดือน-ปี เราจะไม่ต้องใช้คอมม่า

โครงสร้างการใช้

เดือน วันที่, ปี

ตัวอย่างประโยค

She was born on December 10, 1995.
เธอเกิดเมื่อวันที่ 10 ธันวาคม 1995

She was born on 10 December 1995.
เธอเกิดเมื่อวันที่ 10 ธันวาคม 1995

และใช้คอมม่าคั่นระหว่างคำบอกสถานที่ที่ต่างกัน เช่น เมือง จังหวัด รัฐ ประเทศ

โครงสร้างการใช้

  • ชื่อตำบล, ชื่อเขต, ชื่อจังหวัด, ชื่อประเทศ
  • ชื่อเมือง, ชื่อรัฐ, ชื่อประเทศ

ตัวอย่างประโยค

I live in Bangkok, Thailand.
ฉันอาศัยอยู่ในกรุงเทพฯ ประเทศไทย

He came from Chicago, Illinois.
เขามาจากเมืองชิคาโก้ รัฐอิลลินอยส์

8. ใช้คอมม่าหน้า question tag

ใช้คอมม่าคั่นระหว่างประโยคหลักกับ question tag

โครงสร้างการใช้

ประโยคหลัก + , + question tag

ตัวอย่างประโยค

These flowers are beautiful, aren’t they?
ดอกไม้เหล่านี้สวยมาก ว่ามั้ย

You didn’t forget the key, did you?
คุณไม่ได้ลืมกุญแจใช่มั้ย

9. ใช้คอมม่าเมื่อเรียกบุคคลโดยตรง

ใช้คอมม่าคั่นระหว่างคำเรียกบุคคลอื่นกับส่วนอื่นของประโยค เมื่อเราเรียกบุคคลนั้นโดยตรง

โครงสร้างการใช้

  • ประโยคหลัก + , + คำเรียกบุคคล
  • คำเรียกบุคคล + , + ประโยคหลัก

ตัวอย่างประโยค

Dad, where are you?
พ่ออยู่ไหน

See you later, John.
ไว้เจอกันใหม่นะจอห์น

10. ใช้คอมม่าหลังคำขึ้นต้นประโยค

ใช้คอมม่าคั่นระหว่างคำขึ้นต้นประโยคกับประโยคหลัก อย่างเช่น คำทักทาย yes/no

โครงสร้างการใช้

  • คำทักทาย + , + ประโยคหลัก
  • yes/no + , + ประโยคหลัก

ตัวอย่างประโยค

Hello, how is it going?
สวัสดี เป็นยังไงบ้าง

Yes, I live by myself.
ใช่ ฉันอยู่คนเดียว

11. ใช้คอมม่าเพื่อป้องกันการสับสน

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

ตัวอย่างประโยค

I waved at my friend who entered the canteen, and smiled.
ฉันโบกมือให้เพื่อนที่เข้ามาในโรงอาหาร และยิ้มให้เค้า
(คอมม่าทำให้เรารู้ว่าฉันเป็นคนยิ้ม ไม่ใช่เพื่อนยิ้ม)

เป็นยังไงบ้างครับกับหลักการใช้เครื่องหมายคอมม่า (comma) ในภาษาอังกฤษ ทีนี้เพื่อนๆก็คงจะเข้าใจและสามารถนำไปใช้ได้ถูกต้องมากขึ้นแล้วนะครับ

อย่าลืมนะครับ ภาษาอังกฤษยิ่งเรียนรู้ ยิ่งฝึก ก็ยิ่งเก่ง สำหรับบทความนี้ ชิววี่ต้องขอตัวลาไปก่อน See you next time


Semicolon Rules: How to Use the Semicolon when Writing in English | Punctuation Essentials | ESL


An indepth guide on how to use semicolons when writing in English. I will teach you how to use semicolons, explain each of the three rules in detail, and show you several examples. We will go over using semicolons between independent clauses, before conjunctive adverbs, and in complex serial lists.
At the end of the lesson, we will practice using semicolons in five different sentences. Come learn all about colon usage with Sparkle English!
Video Chapters:
0:57 Introduction to Semicolons
1:37 Rule 1: Use a semicolon to connect closely related independent clauses
5:06 Rule 2: Use semicolons between independent clauses joined by a conjunctive adverb
7:58 Rule 3: Use semicolons between items in a series containing internal punctuation
12:40 Semicolon Practice: Which of these sentences requires semicolons?
Check out my other videos in my English Writing Essentials series below:
► Colon Rules https://youtu.be/p40K494L7VQ
► Quotation Marks Rules https://youtu.be/F_yYYoqkZl8
► Apostrophe Rules https://youtu.be/gZ2SNzHON4E
► Capitalization Rules https://youtu.be/KdJL9qJ8t0A
► 8 Comma Rules https://youtu.be/tLlfuIAjaC0
esl learnenglish semicolonrules punctuation sparkleenglish

นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูความรู้เพิ่มเติมที่นี่

Semicolon Rules: How to Use the Semicolon when Writing in English | Punctuation Essentials | ESL

How to use a semicolon – Emma Bryce


View full lesson: http://ed.ted.com/lessons/howtouseasemicolonemmabryce
It may seem like the semicolon is struggling with an identity crisis. It looks like a comma crossed with a period. Maybe that’s why we toss these punctuation marks around like grammatical confetti; we’re confused about how to use them properly. Emma Bryce clarifies best practices for the semiconfusing semicolon.
Lesson by Emma Bryce, animation by Karrot Entertainment.

How to use a semicolon - Emma Bryce

Colons and Semicolons


One of the least understood but quietly significant distinctions of grammar is between a semicolon and a colon; this short films explains: when we should use each construction, why it matters that we do so correctly and what we can hope to achieve with one or the other in our sentences.
For gifts and more from The School of Life, visit our online shop: https://goo.gl/dcr7Pz
Join our mailing list: http://bit.ly/2e0TQNJ
Our website has classes, articles and products to help you think and grow: https://goo.gl/TM73uD
TGUKax
FURTHER READING
You can read more on this and other subjects on our blog, here: https://bit.ly/2sNWzSt
MORE SCHOOL OF LIFE
Visit us in person at our London HQ: https://bit.ly/2JNAqgQ
Watch more films on SELF in our playlist:
http://bit.ly/TSOLself
You can submit translations and transcripts on all of our videos here: https://www.youtube.com/timedtext_cs_panel?c=UC7IcJI8PUf5Z3zKxnZvTBog\u0026tab=2
Find out how more here: https://support.google.com/youtube/answer/6054623?hl=enGB

SOCIAL MEDIA
Feel free to follow us at the links below:
TGUKax
Facebook: https://www.facebook.com/theschooloflifelondon/
Twitter: https://twitter.com/TheSchoolOfLife
Instagram: https://www.instagram.com/theschooloflifelondon/

CREDITS
Produced in collaboration with:

Illustrations by Nina Cosford www.ninacosford.com

Animation by Ali Graham www.grarg.com TheSchoolOfLife

Colons and Semicolons

ใช้ Comma พื้นฐาน 1/3


บทเรียนราคาแพงของ comma
ครูนีมมาแนะนำหลักการใช้ เครื่องหมายภาษาอังกฤษที่มักใช้ผิด วางสลับที่กันเสมอ มี 3 คลิป
Subscribe ครูนีม English Upgrade ทาง YouTube
และติดตาม @kruneemupgrade ทาง Facebook
https://www.facebook.com/kruneemupgrade/

ใช้ Comma พื้นฐาน 1/3

Punctuation Explained (by Punctuation!) | Scratch Garden


Learn about punctuation from the punctuation marks themselves!
GET THE PUNCTUATION BOOK! http://scratchgarden.com/book/
📖 THIS VIDEO NOW HAS A GREAT SUPPLEMENTAL LEARNING POSTER! 📖 https://scratchgarden.com/shop/item/punctuationposter/
Our 2ND CHANNEL is on Patreon! ►► https://www.patreon.com/scratchgarden ◄◄
Whether you are teaching punctuation for ESL \u0026 EFL or writing sentences for kids, the Punctuation Explained video will help to make your English lesson fun and understandable!
Primary Teaching Points: punctuation, proper usage of period, question mark, exclamation mark, and comma
Related Videos: Contractions! https://youtu.be/gubPH3WEurg
Check out our full Learning Songs Playlist here: https://www.youtube.com/playlist?list=PL_ym6QHjS1szUhzH9URPbDflLczfPHF6P
Scratch Garden makes entertaining educational videos for people that like to laugh and learn! Please Subscribe to see more great fun learning videos from Scratch Garden! https://goo.gl/1biPjA
Our ‘2nd Channel’ is on Patreon! ▶ https://www.patreon.com/scratchgarden
OUR FIRST BOOK IS NOW AVAILABLE! http://amzn.to/2Fm2B0L
Website: https://www.scratchgarden.com
Instagram: https://www.instagram.com/scratchgarden
Facebook: https://www.facebook.com/scratchgarden
ESL punctuation teachingEnglish

Punctuation Explained (by Punctuation!) | Scratch Garden

นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูวิธีอื่นๆLEARN FOREIGN LANGUAGE

ขอบคุณมากสำหรับการดูหัวข้อโพสต์ semicolon คือ

Leave a Reply

Your email address will not be published. Required fields are marked *