|
| 1 | +# 1.2 $GOPATH และ workspace |
| 2 | + |
| 3 | +## $GOPATH |
| 4 | + |
| 5 | +Go มีกรรมวิธีในการจัดการไฟล์ code ที่เป็นเอกลักษณ์ ด้วยการเพิ่มไดเร็คทอรีีที่เรียกว่า `$GOPATH` เพื่อใช้ในการเก็บ code ของ Go ทั้งหมดในเครื่อง ขอให้สังเกตุว่าเป็นคนละตัวกับค่าตัวแปร environment `$GOROOT` ซึ่งเป็นค่าที่บอกว่า Go ถูกติดตั้งไว้ที่ใดในเครื่อง โดยเราต้องกำหนดค่าให้กับ `$GOPATH` ก่อนที่จะสามารถใช้งานภาษาได้ โดยในระบบ *nix ทั้งหลายนั้น จะมีไฟล์ `.profile` อยู่ และเราต้องเพิ่มคำสั่ง export ที่อยู่ด้านล่างนี้เข้าไปในไฟล์ แนวคิดเบื้องหลัง gopath นี้เป็นเรื่องใหม่ ที่จะทำให้เราสามารถเชื่อมไปที่ code ของ Go ได้อย่างรวดเร็วและชัดเจน |
| 6 | + |
| 7 | +เริ่มตั้งแต่ Go 1.8 เป็นต้นมา ค่าของตัวแปร GOPATH จะถูกกำหนดค่าให้อัตโนมัติหากเราไม่ได้กำหนดให้เป็นอย่างอื่น โดยจะมีค่่าเป็น `$HOME/go` บนระบบ Unix และ `$USERPROFILE%/go` บน Windows |
| 8 | + |
| 9 | +บนระบบคล้าย Unix ทั้งหลาย ค่าตัวแปรควรจะถูกตั้งค่าดังนี้: |
| 10 | + |
| 11 | + export GOPATH=${HOME}/mygo |
| 12 | + |
| 13 | +บน Windows เราจำเป็นต้องสร้างตัวแปร environment GOPATH ขึ้นมา แล้วกำหนดค่าให้เป็น `c:\mygo` ( ***ค่านี้อาจมีค่าแตกต่างออกไปขึ้นอยู่กับว่า workspace อยู่ที่ไหน*** ) |
| 14 | + |
| 15 | +เป็นไปได้ที่จะมีหลาย path (workspace) ใน `$GOPATH` แต่เราต้องจำให้ได้ว่าต้องใช้ `:` (`;` สำหรับ Windows) คั่นระหว่างกลางแต่ละค่า โดยจุดนี้ `go get` จะบันทึกข้อมูลไปที่ path แรกที่ระบุใน `$GOPATH` แต่ขอแนะนำว่าไม่ควรใช้วิธีนี้ นอกจากนี้แล้วนับว่าเป็นเรื่องแย่ที่เราจะสร้างโฟลเดอร์โดยตั้งชื่อด้วยชื่อของโปรเจ็คแล้ววางไว้ใน `$GOPATH` นี่จะเป็นการทำลายทุกอย่างที่ผู้สร้างตั้งใจที่จะให้เป็นความเปลี่ยนแปลงของภาษา ด้วยเหตุผลว่าหากเราสร้างโฟลเดอร์ไว้ใน `$GOPATH` โดยตรงแล้ว เวลาที่เราจะอ้างถึง package เราจะต้องอ้างถึงโดยใช้ <packagename> โดยตรง และนี่จะทำให้เกิดปัญหาขึ้นเนื่องจาก `go get` จะไม่สามารถหา package พบ ได้โปรดทำตาม convention มันมีเหตุผลที่มันถูกสร้างขึ้นมา |
| 16 | + |
| 17 | +ใน `$GOPATH` นั้นต้องประกอบด้วย 3 โฟลเดอร์ดังนี้: |
| 18 | + |
| 19 | +- `src` สำหรับเก็บไฟล์ source code ที่มีนามสกุล .go, .c, .g, .s |
| 20 | +- `pkg` สำหรับเก็บไฟล์ที่ได้จากการคอมไพล์ซึ่งจะมีนามสกุลเป็น .a |
| 21 | +- `bin` สำหรับเก็บไฟล์ประเภท executable |
| 22 | + |
| 23 | +ในหนังสือเล่มนี้ จะใช้ `mygo` เป็น path เดียวที่มีใน `$GOPATH` |
| 24 | + |
| 25 | +## ไดเร็คทอรีที่ใช้เก็บ package |
| 26 | + |
| 27 | +ในการสร้าง source file และโฟลเดอร์ของ package เช่น `$GOPATH/src/mymath/sqrt.go` (`mymath` คือชื่อ package) ( ***ผู้เขียนใช้ชื่อ `mymath` เป็นทั้งชื่อ package และเป็นชื่อโฟลเดอร์ที่เก็บ source file ของ package***) |
| 28 | +ทุกครั้งที่สร้าง package ใหม่ เราควรสร้างโฟลเดอร์ใหม่ไว้ในไดเร็คทอรี `src` ยกเว้นโฟลเดอร์ main เนื่องจากโฟลเดอร์ `main` จะสร้างหรือไม่ก็ได้ไม่บังคับ โดยปรกติแล้วชื่อของโฟลเดอร์จะตั้งชื่อตามชื่อ package จะจะถูกเรียกใช้ และสามารถสร้างไดเร็คทอรีย่อยกี่ชั้นก็ได้ตามที่ต้องการ ยกตัวอย่างเช่น ถ้าสร้างไดเร็คทอรี่ `$GOPATH/src/github.com/astaxie/beedb` ชื่อ path ของ package ก็จะเป็น `github.com/astaxie/beedb` และชื่อ package เองก็คือชื่อไดเร็คทอรีตัวสุดท้ายของ path ซึ่งในกรณีนี้ก็คือ `beedb` |
| 29 | + |
| 30 | +รันคำสั่งดังนี้ ( ***ตอนนี้ผู้เขียนกลับมาพูดถึงตัวอย่าง*** ) |
| 31 | + |
| 32 | + cd $GOPATH/src |
| 33 | + mkdir mymath |
| 34 | + |
| 35 | +สร้างไฟล์ใหม่ชื่อ `sqrt.go` และเนื้อหาของไฟล์ดังนี้ |
| 36 | + |
| 37 | +```Go |
| 38 | +// Source code of $GOPATH/src/mymath/sqrt.go |
| 39 | +package mymath |
| 40 | + |
| 41 | +func Sqrt(x float64) float64 { |
| 42 | + z := 0.0 |
| 43 | + for i := 0; i < 1000; i++ { |
| 44 | + z -= (z*z - x) / (2 * x) |
| 45 | + } |
| 46 | + return z |
| 47 | +} |
| 48 | +``` |
| 49 | + |
| 50 | +ตอนนี้เราได้สร้างไดเร็คทอรีของ package และเขียน code เรียบร้อยแล้ว และขอแนะนำให้ใช้ชื่อ package เป็นชื่อเดียวกับไดเร็คทอรี และ source file ทั้งหมดของ package เก็บไว้ภายใต้ไดเร็คทอรีนี้่่ |
| 51 | + |
| 52 | +## การคอมไพล์ package |
| 53 | + |
| 54 | +หลังจากสร้าง package ตามขั้นตอนเสร็จแล้ว เราก็ลองมาสั่งคอมไพล์ package กันดู โดยการคอมไพล์ package สามารถทำได้ 2 วิธีดังนี้: |
| 55 | + |
| 56 | +1. ไปที่ path ในไดเร็คทอรีของ package แล้วใช้คำสั่ง `go install` |
| 57 | +2. หรือใช้คำสั่งเหมือนด้านบน แต่ไม่ต้องใส่ชื่อไฟล์ เช่น `go install mymath` |
| 58 | + |
| 59 | +หลังจากที่คอมไพล์เสร็จเรียบร้อยแล้ว ให้เข้าไปที่โฟลเดอร์ด้วยคำสั่ง |
| 60 | + |
| 61 | + cd $GOPATH/pkg/${GOOS}_${GOARCH} |
| 62 | + // you can see the file was generated |
| 63 | + mymath.a |
| 64 | + |
| 65 | +จะเห็นว่ามีไฟล์ซึ่งมีนามสกุล `.a` อยู่ ซึ่งก็คือไฟล์่่ binary ของ package นั่นเอง แล้วเราจะเรียกใช้งานมันยังไงหละ? |
| 66 | + |
| 67 | +แน่นอนว่าเราจำเป็นต้องสร้างแอพพลิเคชั่นใหม่ขึ้นมา เพื่อเรียกใช้งาน package นี้ |
| 68 | + |
| 69 | +ให้ทำการสร้างแอพพลิเคชั่นใหม่ชื่อ `mathapp` |
| 70 | + |
| 71 | + cd $GOPATH/src |
| 72 | + mkdir mathapp |
| 73 | + cd mathapp |
| 74 | + vim main.go |
| 75 | + |
| 76 | +แล้วใส่เนื้อหาดังต่อไปนี้ลงในไฟล์ main.go |
| 77 | + |
| 78 | +```Go |
| 79 | + |
| 80 | +//$GOPATH/src/mathapp/main.go source code. |
| 81 | +package main |
| 82 | + |
| 83 | +import ( |
| 84 | + "mymath" |
| 85 | + "fmt" |
| 86 | +) |
| 87 | + |
| 88 | +func main() { |
| 89 | + fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +ในการคอมไพล์แอพพลิเคชั่น เราต้องเข้าไปอยู่ที่ไดเร็คทอรีของแอพพลิเคชั่นที่ต้องการคอมไพล์ ซึ่งในที่นี้คือ `$GOPATH/src/mathapp` แล้วจึงสั่งคำสั่ง `go install` เมื่อคอมไพล์เสร็จแล้วจะเห็นไฟล์ที่ชื่อว่า `myapp` เกิดขึ้นมาในไดเร็คทอรี `$GOPATH/bin/` โดยเราสามารถสั่งรับแอพพลิเคชั่นโดยใช้คำสั่ง `./mathapp` เมื่อทำงานเสร็จแล้วเราควรจะเห็นข้อความปรากฎที่หน้าจอ terminal ดังนี้ |
| 94 | + |
| 95 | + Hello world. Sqrt(2) = 1.414213562373095 |
| 96 | + |
| 97 | +## การติดตั้ง package เพิ่มเติม |
| 98 | + |
| 99 | +Go มาพร้อมกับเครื่องมือที่ใช้ในการติดตั้ง package เสริม ซึ่งได้แก่คำสั่งที่เรียกว่า `go get` โดยรองรับ opensource comunity เกือบทุกที่ รวมถึง Github, Google Code, BitBucket และ Launchpad |
| 100 | + |
| 101 | + go get github.com/astaxie/beedb |
| 102 | + |
| 103 | +โดยสามารถใช้ `go get -u …` ในการอัพเดท package และยังสามารถติดตั้ง package ที่เป็น dependency ให้โดยอัตโนมัติด้วย |
| 104 | + |
| 105 | +ซึ่งเครื่องมือนี้จะใช้ version control ที่แตกต่างกันสำหรับแต่ละ opensource platform ยกตัวอย่างเช่น จะใช้่่ `git` สำหรับ Github และใช้ `hg` สำหรับ Google Code ดังนั้นเราจำเป็นที่จะต้องติดตั้งเครื่องมือ version control เหล่านี้ก่อนที่เราจะใช้ `go get` ได้ |
| 106 | + |
| 107 | +หลังจากที่รันคำสั่งที่กล่าวมาแล้ว โครงสร้างไดเร็คทอรีควรมีหน้าตาดังนี้ |
| 108 | + |
| 109 | + $GOPATH |
| 110 | + src |
| 111 | + |-github.com |
| 112 | + |-astaxie |
| 113 | + |-beedb |
| 114 | + pkg |
| 115 | + |--${GOOS}_${GOARCH} |
| 116 | + |-github.com |
| 117 | + |-astaxie |
| 118 | + |-beedb.a |
| 119 | + |
| 120 | +อันที่จริงแล้ว `go get` จะทำการ clone source code ไปเก็บไว้ที่ `$GOPATH/src` ในเครื่อง เสร็จแล้วให้สั่ง `go install` จะทำให้เราสามารถใช้ package ซึ่งมาจากที่อื่น (remote packages) ได้ในแบบเดียวกับที่เราใช้ package ที่อยู่ในเครื่องของเราเอง |
| 121 | + |
| 122 | +```Go |
| 123 | +import "github.com/astaxie/beedb" |
| 124 | +``` |
| 125 | + |
| 126 | +## โครงสร้างไดเร็คทอรี่แบบสมบูรณ์ |
| 127 | + |
| 128 | +หากเราทำตามคำสั่งที่กล่าวมาแล้วทั้งหมด โครงสร้างไดเร็คทอรีในเครื่องของเราควรจะมีลักษณะดังนี้ |
| 129 | + |
| 130 | + bin/ |
| 131 | + mathapp |
| 132 | + pkg/ |
| 133 | + ${GOOS}_${GOARCH}, such as darwin_amd64, linux_amd64 |
| 134 | + mymath.a |
| 135 | + github.com/ |
| 136 | + astaxie/ |
| 137 | + beedb.a |
| 138 | + src/ |
| 139 | + mathapp |
| 140 | + main.go |
| 141 | + mymath/ |
| 142 | + sqrt.go |
| 143 | + github.com/ |
| 144 | + astaxie/ |
| 145 | + beedb/ |
| 146 | + beedb.go |
| 147 | + util.go |
| 148 | + |
| 149 | +ตอนนี้เราจะเห็นโครงสร้างได้อย่างชัดเจนว่า `bin` จะเป็นที่อยู่ของไฟล์ executable ส่วน `pkg` จะเป็นที่อยู่ของไฟล์ที่ได้จากการคอมไพล์ และ `src` คือส่วนที่เก็บ source file ของ package นั่นเอง |
| 150 | + |
| 151 | +(รูปแบบของตัวแปร environment บน Windows คือ `%GOPATH%` แต่ว่าอย่างไรก็ตาม หนังสือเล่มนี้จะเป็นสไตล์ของ Unix ดังนี้ผู้ใช้งาน Windows จึงต้องแก้ให้ถูกต้องด้วยตัวเอง) |
| 152 | + |
| 153 | +## Links |
| 154 | + |
| 155 | +- [Directory](preface.md) |
| 156 | +- บทก่อนหน้า: [การติดตั้ง](01.1.md) |
| 157 | +- บทถัดไป: [คำสั่งของ Go](01.3.md) |
0 commit comments