Hello, World!
เมื่อคุณทำการติดตั้ง Rust เรียบร้อยแล้ว ก็ถึงเวลาที่จะเขียนโปรแกรม Rust แรกของคุณ ตามธรรมเนียมปฏิบัติของการเรียนรู้ภาษาใหม่ มักจะเริ่มต้นด้วยการเขียนโปรแกรมขนาดเล็กเพื่อพิมพ์ข้อความ Hello, world! แสดงผลบนหน้าจอ ดังนั้นเรามาทำแบบเดียวกันในที่นี้กันเลย!
หมายเหตุ: หนังสือเล่มนี้ตั้งสมมติฐานว่าคุณมีความคุ้นเคยพื้นฐานเกี่ยวกับบรรทัดคำสั่ง (command line) อยู่บ้าง ภาษา Rust ไม่ได้มีข้อกำหนดเป็นพิเศษเกี่ยวกับเครื่องมือแก้ไขโค้ด เครื่องมือพัฒนา หรือตำแหน่งที่เก็บไฟล์โค้ดของคุณ ดังนั้น หากคุณต้องการเขียนโค้ดด้วยโปรแกรมพัฒนาแบบรวม (IDE) แทนการใช้บรรทัดคำสั่ง ก็สามารถเลือกใช้ IDE ที่คุณชื่นชอบได้ตามต้องการ ปัจจุบัน IDE หลายตัวรองรับการทำงานกับภาษา Rust ในระดับที่น่าพอใจ โดยสามารถตรวจสอบรายละเอียดได้จากเอกสารคู่มือของ IDE นั้นๆ ทั้งนี้ทีมพัฒนา Rust ได้มุ่งเน้นการพัฒนาการทำงานร่วมกับ IDE อย่างดีเยี่ยมผ่าน
rust-analyzerสามารถดูรายละเอียดเพิ่มเติมได้ที่ ภาคผนวก D
การตั้งค่าโฟลเดอร์โครงการ (Project Directory Setup)
คุณจะเริ่มต้นด้วยการสร้างโฟลเดอร์ (directory) สำหรับใช้จัดเก็บไฟล์โค้ด Rust สำหรับตัวภาษา Rust เองไม่มีเงื่อนไขว่าโค้ดของคุณจะต้องจัดเก็บไว้ที่ใด แต่เพื่อความสะดวกในการฝึกทำแบบฝึกหัดและโครงการต่างๆ ในหนังสือเล่มนี้ เราแนะนำให้สร้างโฟลเดอร์ชื่อ projects ไว้ในโฟลเดอร์หลักของผู้ใช้ (home directory) และจัดเก็บทุกโครงการของคุณไว้ที่นั่น
ให้เปิดเทอร์มินัลแล้วพิมพ์ป้อนคำสั่งดังต่อไปนี้ เพื่อสร้างโฟลเดอร์ชื่อ projects และสร้างโฟลเดอร์โครงการ “Hello, world!” ย่อยอยู่ภายในโฟลเดอร์ projects นั้น
สำหรับ Linux, macOS และ PowerShell บน Windows ให้ป้อนคำสั่งดังนี้:
$ mkdir ~/projects
$ cd ~/projects
$ mkdir hello_world
$ cd hello_world
สำหรับ Windows CMD ให้ป้อนคำสั่งดังนี้:
> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world
พื้นฐานของโปรแกรมภาษา Rust
ถัดไป ให้สร้างไฟล์ซอร์สโค้ดใหม่และตั้งชื่อว่า main.rs ไฟล์ของภาษา Rust จะต้องลงท้ายด้วยนามสกุล .rs เสมอ หากคุณต้องการใช้คำหลายคำในชื่อไฟล์ ตามข้อตกลงสากลแนะนำให้ใช้เครื่องหมายขีดล่าง (underscore) ในการแยกคำเหล่านั้น ตัวอย่างเช่น เลือกใช้ชื่อ hello_world.rs แทนที่จะเขียนติดกันเป็น helloworld.rs
จากนั้นให้เปิดไฟล์ main.rs ที่คุณเพิ่งสร้างขึ้น และพิมพ์ป้อนโค้ดตามตัวอย่างใน Listing 1-1
fn main() {
println!("Hello, world!");
}
บันทึกไฟล์และย้อนกลับไปที่หน้าต่างเทอร์มินัลของคุณในโฟลเดอร์ ~/projects/hello_world สำหรับ Linux หรือ macOS ให้ป้อนคำสั่งต่อไปนี้เพื่อคอมไพล์และสั่งรันไฟล์งาน:
$ rustc main.rs
$ ./main
Hello, world!
สำหรับ Windows ให้ป้อนคำสั่ง .\main แทนที่จะพิมพ์ ./main:
> rustc main.rs
> .\main
Hello, world!
ไม่ว่าคุณจะใช้งานระบบปฏิบัติการใดก็ตาม ข้อความ Hello, world! ควรจะถูกพิมพ์แสดงผลออกมาบนหน้าต่างเทอร์มินัล หากคุณไม่พบผลลัพธ์ดังกล่าวนี้ ให้ย้อนกลับไปดูวิธีแก้ไขปัญหาในหัวข้อ “การแก้ไขปัญหาเบื้องต้น” ในส่วนของการติดตั้งเพื่อศึกษาช่องทางการรับความช่วยเหลือ
หากข้อความ Hello, world! พิมพ์แสดงผลขึ้นมาได้สำเร็จ ขอแสดงความยินดีด้วย! คุณได้เขียนโปรแกรม Rust แรกขึ้นมาอย่างเป็นทางการแล้ว และนั่นส่งผลให้คุณกลายเป็นนักเขียนโปรแกรม Rust อย่างเต็มตัว—ยินดีต้อนรับ!
โครงสร้างส่วนประกอบของโปรแกรม Rust (The Anatomy of a Rust Program)
เรามาลองทบทวนรายละเอียดของโปรแกรม “Hello, world!” นี้กันอย่างละเอียด นี่คือชิ้นส่วนแรกของปริศนา:
fn main() {
}
บรรทัดเหล่านี้ทำการนิยามฟังก์ชันชื่อว่า main ฟังก์ชัน main มีความสำคัญเป็นพิเศษ: มันเป็นโค้ดส่วนแรกที่จะถูกสั่งให้รันเสมอในโปรแกรม Rust ทุกตัวที่รันได้ (executable) ในจุดนี้ บรรทัดแรกทำการประกาศฟังก์ชันชื่อ main ที่ไม่มีพารามิเตอร์ส่งเข้ามาและไม่มีการส่งค่าใดๆ กลับ หากฟังก์ชันมีพารามิเตอร์ พารามิเตอร์เหล่านั้นจะถูกระบุไว้ภายในวงเล็บ (())
ตัวฟังก์ชัน (function body) จะถูกครอบไว้ด้วยวงเล็บปีกกา {} ภาษา Rust กำหนดให้คุณต้องมีวงเล็บปีกกาครอบส่วนเนื้อหาฟังก์ชันทั้งหมด รูปแบบการเขียนโค้ดที่ดีคือกำหนดให้เครื่องหมายเปิดวงเล็บปีกกาจัดวางอยู่ในบรรทัดเดียวกันกับการประกาศฟังก์ชัน โดยเว้นระยะห่างหนึ่งช่องว่างระหว่างนั้น
หมายเหตุ: หากคุณต้องการให้สไตล์การเขียนโค้ดของคุณเป็นไปตามมาตรฐานเดียวกันในทุกโครงการของ Rust คุณสามารถเรียกใช้เครื่องมือจัดรูปแบบอัตโนมัติชื่อ
rustfmtเพื่อช่วยจัดสไตล์โค้ดของคุณในรูปแบบที่ต้องการได้ (ศึกษาข้อมูลrustfmtเพิ่มเติมได้ใน ภาคผนวก D) ซึ่งทีมงาน Rust ได้รวมเครื่องมือตัวนี้มาให้พร้อมกับชุดติดตั้งมาตรฐานของ Rust อยู่แล้ว เช่นเดียวกับคอมไพเลอร์rustcดังนั้นมันจึงควรพร้อมใช้งานอยู่ในคอมพิวเตอร์ของคุณแล้ว!
ส่วนของเนื้อหาภายในฟังก์ชัน main จะเก็บโค้ดดังต่อไปนี้:
#![allow(unused)]
fn main() {
println!("Hello, world!");
}
โค้ดบรรทัดนี้ทำหน้าที่ทั้งหมดของโปรแกรมขนาดเล็กนี้ นั่นคือการสั่งพิมพ์ข้อความขึ้นไปบนหน้าจอ มีรายละเอียดสำคัญ 3 ประการที่คุณต้องสังเกตในจุดนี้
ประการแรก คำสั่ง println! เป็นการเรียกใช้มาโคร (macro) ของ Rust หากคำสั่งนี้เป็นการเรียกฟังก์ชันปกติทั่วไป มันจะถูกเขียนในรูปแบบ println (โดยไม่มีเครื่องหมาย !) มาโครของ Rust คือวิถีทางเขียนโค้ดที่ใช้สำหรับสร้างโค้ดอื่นขึ้นมาเพื่อช่วยขยายขอบเขตความสามารถของไวยากรณ์ Rust ซึ่งเราจะพูดคุยในรายละเอียดเชิงลึกเกี่ยวกับเรื่องนี้กันใน บทที่ 20 ในปัจจุบันนี้ คุณเพียงจำเป็นต้องทราบว่าการมีอักขระ ! อยู่ด้วย หมายถึงคุณกำลังเรียกใช้งานมาโครแทนที่จะเป็นฟังก์ชันธรรมดา และมาโครไม่ได้ดำเนินตามกฎเกณฑ์เดียวกันกับฟังก์ชันทั่วไปเสมอไป
ประการที่สอง คุณจะเห็นข้อมูลข้อความ "Hello, world!" เราส่งข้อความนี้ผ่านเข้าไปเป็นอาร์กิวเมนต์ให้กับ println! และข้อความดังกล่าวจะถูกพิมพ์แสดงผลออกมาบนหน้าจอ
ประการที่สาม เราสิ้นสุดบรรทัดคำสั่งด้วยเครื่องหมายอัฒภาคหรือเซมิโคลอน (;) ซึ่งระบุว่านิพจน์ (expression) นี้เสร็จสิ้นลงแล้ว และพร้อมสำหรับการเริ่มต้นในนิพจน์ถัดไป โค้ดภาษา Rust ส่วนใหญ่จะจบบรรทัดด้วยเครื่องหมายเซมิโคลอน
การคอมไพล์และการประมวลผลคำสั่ง (Compilation and Execution)
คุณเพิ่งสั่งรันโปรแกรมที่สร้างขึ้นใหม่เสร็จสิ้นไป ดังนั้นเรามาวิเคราะห์รายละเอียดทีละขั้นตอนในกระบวนการทำงานนี้กัน
ก่อนที่จะสั่งรันโปรแกรมภาษา Rust ได้ คุณจำเป็นต้องทำการคอมไพล์โปรแกรมผ่านการเรียกใช้งานคอมไพเลอร์ Rust โดยพิมพ์ป้อนคำสั่ง rustc และระบุชื่อไฟล์ซอร์สโค้ดของคุณลงไปด้วย เช่นนี้:
$ rustc main.rs
หากคุณเคยมีประสบการณ์เขียนภาษา C หรือ C++ มาก่อน คุณจะสังเกตได้ว่าคำสั่งนี้คล้ายคลึงกับการเรียกใช้งาน gcc หรือ clang หลังจากทำการคอมไพล์สำเร็จแล้ว Rust จะส่งไฟล์ไบนารีที่เปิดรันทำงานได้ออกมา (binary executable)
สำหรับ Linux, macOS และ PowerShell บน Windows คุณสามารถตรวจสอบไฟล์ที่รันระบบดังกล่าวได้โดยการป้อนคำสั่ง ls ในเชลล์ของคุณ:
$ ls
main main.rs
สำหรับ Linux และ macOS คุณจะเห็นไฟล์ปรากฏอยู่ 2 ไฟล์ด้วยกัน ส่วนใน PowerShell บน Windows คุณจะพบไฟล์ 3 ไฟล์ ซึ่งเหมือนกับสิ่งที่คุณพบเมื่อเรียกใช้โปรแกรม CMD โดยใน CMD ของ Windows ให้คุณป้อนคำสั่งดังต่อไปนี้:
> dir /B %= the /B option says to only show the file names =%
main.exe
main.pdb
main.rs
การทำงานนี้จะแสดงไฟล์ซอร์สโค้ดที่ลงท้ายด้วยนามสกุล .rs, ไฟล์ที่รันระบบได้ (main.exe สำหรับ Windows แต่จะชื่อว่า main ในแพลตฟอร์มอื่นๆ) และเมื่อคุณใช้งาน Windows จะมีไฟล์สำหรับเก็บข้อมูลการดีบักลงท้ายด้วยนามสกุล .pdb แสดงเพิ่มขึ้นมาด้วย และจากจุดนี้ คุณสามารถสั่งรันไฟล์ main หรือ main.exe ได้ดังนี้:
$ ./main # หรือ .\main สำหรับ Windows
หากไฟล์ main.rs ของคุณเก็บโค้ดของโปรแกรม “Hello, world!” อยู่ คำสั่งบรรทัดนี้จะพิมพ์แสดงผลข้อความ Hello, world! ออกมาทางเทอร์มินัลของคุณ
หากคุณมีความคุ้นเคยกับภาษาที่เป็นแบบไดนามิกมากกว่า เช่น Ruby, Python หรือ JavaScript คุณอาจจะไม่คุ้นเคยกับขั้นตอนการคอมไพล์และการรันโปรแกรมที่เป็นขั้นตอนที่แยกออกจากกัน ภาษา Rust เป็นภาษาประเภท คอมไพล์ล่วงหน้า (ahead-of-time compiled) ซึ่งหมายความว่าคุณสามารถคอมไพล์โปรแกรมแล้วส่งมอบเฉพาะไฟล์ที่รันผลลัพธ์สำเร็จรูปนี้ให้แก่ผู้อื่นนำไปเปิดรันทำงานได้โดยตรงโดยที่เครื่องปลายทางเหล่านั้นไม่จำเป็นต้องติดตั้ง Rust เลยก็ได้ แต่หากคุณส่งมอบไฟล์ .rb, .py หรือ .js ให้คนอื่น เครื่องของพวกเขาจำเป็นต้องมีการติดตั้งโปรแกรมสำหรับแปรภาษาและรันภาษา Ruby, Python หรือ JavaScript (ตามลำดับ) เตรียมไว้ด้วย แต่ทว่าข้อดีในกลุ่มภาษานั้นคือคุณใช้เพียงคำสั่งเดียวในการสั่งให้ระบบคอมไพล์และทำงาน ทุกสิ่งล้วนเป็นเรื่องของการแลกเปลี่ยนในการออกแบบโครงสร้างภาษาโปรแกรม
การเลือกใช้เพียงคำสั่งคอมไพล์ผ่าน rustc อาจเหมาะสำหรับโปรแกรมที่มีขนาดเล็กและเรียบง่าย แต่เมื่อใดก็ตามที่โครงการของคุณขยายใหญ่ขึ้น คุณย่อมต้องการการบริหารจัดการตัวเลือกตั้งค่าต่างๆ ได้สะดวก และเพิ่มความง่ายในแบ่งปันส่งต่อไฟล์โค้ดของคุณ ในหัวข้อถัดไป เราจะขอแนะนำเครื่องมือจัดการ Cargo ซึ่งจะเข้ามาช่วยเหลือตอบโจทย์คุณในการพัฒนาโปรแกรมภาษา Rust ในชีวิตจริง