ปีที่มีการนำภาษาโปรแกรมสนิมมาใช้ สถานะปัจจุบันของภาษา Rust คืออะไร? สลับไปที่คาร์โก้

ถึงตอนนี้คุณอาจสังเกตเห็นว่าไวยากรณ์ของภาษาโปรแกรมที่เป็นปัญหานั้นคล้ายคลึงกับไวยากรณ์ของภาษาเช่น C/C++ มาก เนื่องจากในทั้งสองกรณีมีการใช้เครื่องหมายทับสองอันเพื่อเน้นความคิดเห็น บล็อกโค้ดจะล้อมรอบด้วยเครื่องหมายปีกกา และอาร์กิวเมนต์ของฟังก์ชันจะล้อมรอบด้วยวงเล็บ คุณควรจำไว้ว่ามีการประกาศใช้ฟังก์ชันต่างๆ คำหลัก fn และทุกโปรแกรมจะต้องมีฟังก์ชัน main() เครื่องหมายอัศเจรีย์หลังชื่อฟังก์ชัน println ในกรณีนี้ระบุว่ามีการใช้มาโคร (โดยพื้นฐานแล้วจะเป็น wrapper ที่สะดวกรอบฟังก์ชันการพิมพ์จากไลบรารีรันไทม์ของ Rust)

หากต้องการคอมไพล์โปรแกรม เพียงรันคำสั่ง:

Rustc hello.rs

เป็นผลให้ไฟล์ไบนารี่ชื่อ hello ควรปรากฏในไดเร็กทอรีพร้อมกับไฟล์ซอร์สโค้ดของโปรแกรม เพื่อดำเนินการ เพียงแค่รัน command./hello แต่ถ้าคุณใส่ใจกับขนาดของไฟล์นี้ คุณจะตกใจเล็กน้อย: มันจะเกิน 800 KB และทั้งหมดนี้จำเป็นสำหรับโปรแกรมง่าย ๆ ที่จะใช้งานได้เหรอ? โดยค่าเริ่มต้นคอมไพเลอร์ Rust จะทำ การเชื่อมโยงแบบคงที่ไลบรารีรันไทม์ส่วนใหญ่จะรวมอยู่ในโปรแกรม ดังนั้นคุณจึงสามารถคัดลอกไบนารีไปยังระบบที่ไม่ได้ติดตั้งไลบรารีรันไทม์ Rust และรันได้โดยไม่มีปัญหาใดๆ อย่างไรก็ตาม คุณยังสามารถบอกให้คอมไพลเลอร์ดำเนินการปรับให้เหมาะสมและลิงก์แบบไดนามิกได้:

Rustc -OC ชอบ-ไดนามิก hello.rs

ตอนนี้คุณจะได้ขนาดไบนารี่ที่สามารถจัดการได้มากขึ้นคือ 8 KB แต่ถ้าคุณใช้ ldd คุณจะพบว่าสำหรับ การดำเนินการที่ถูกต้องโปรแกรมจะต้องมีอยู่ในระบบ ไลบรารีแบบไดนามิก libstd-<версия>.ดังนั้น .

ไวยากรณ์ภาษาโปรแกรม

ตอนนี้เราสามารถคอมไพล์และรันโปรแกรมใน Rust ได้แล้ว ฉันเสนอให้เข้าใจไวยากรณ์ของภาษาการเขียนโปรแกรมนี้ และเน้นความแตกต่างจากไวยากรณ์ของภาษาการเขียนโปรแกรมเช่น C, C++ และภาษาอื่นที่คล้ายคลึงกัน:

Fn doubler (x: i32) -> i32 ( x * 2 ) fn main () ( ให้ a: i32 = 5; ให้ b; b = doubler(a); println!("a คูณ 2 ()", b) ; จับคู่ b ( 1 ... 10 => println!("From 1 to 10"), _ => println!("Another number"), ) )

หากคุณคุ้นเคยกับการทำงานกับภาษา C/C++ คุณอาจคิดว่าโค้ดนี้แปลก แต่ก็ค่อนข้างสมเหตุสมผล เริ่มจากฟังก์ชัน main() กันก่อน: ในบรรทัดแรกของให้เราประกาศตัวแปรจำนวนเต็ม 32 บิต a และกำหนดค่าเริ่มต้นเป็น 5 เราสามารถข้ามการระบุประเภทของตัวแปรได้ (i32 เป็นประเภทตัวแปรมาตรฐาน) และไม่ได้กำหนดค่าเริ่มต้นให้กับมันด้วย และในกรณีนี้มันจะมีค่าเป็นศูนย์ โปรดทราบว่าหากคุณประกาศตัวแปรและกำหนดค่าเฉพาะให้กับตัวแปรในลักษณะเดียวกับตัวแปร a ในตัวอย่าง คุณจะไม่สามารถเปลี่ยนค่าได้ในภายหลัง ดังนั้นข้อความแสดงข้อผิดพลาดจะถูกสร้างขึ้นเมื่อรวบรวมข้อมูลโค้ดต่อไปนี้:

ให้: i32 = 5; ก = 10;

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

ให้ mut a: i32 = 5;

เหตุใดจึงจำเป็น? นี่เป็นงานพิเศษใช่ไหม? โดยพื้นฐานแล้วนี่เป็นเรื่องจริง แต่ในทางกลับกัน คุณลักษณะนี้ภาษาการเขียนโปรแกรมช่วยในการพัฒนาโปรแกรมที่ปลอดภัย คุณควรทำให้ตัวแปรไม่แน่นอนซึ่งค่าจำเป็นต้องเปลี่ยนจริงๆ เท่านั้น Rust บังคับให้คุณใช้รายละเอียดมากเท่าที่จำเป็นเพื่ออธิบายวิธีการทำงานของโปรแกรมอย่างชัดเจน: บรรทัดด้านบนคือการประกาศตัวแปรจำนวนเต็ม a ที่มีเครื่องหมาย ซึ่งมีขนาด 32 บิตพอดี พร้อมความสามารถในการเปลี่ยนค่าของมันในอนาคต

ต่อไป เราเรียกฟังก์ชัน doubler ที่มีตัวแปร a เป็นอาร์กิวเมนต์ และเก็บค่าที่ส่งคืนไว้ในตัวแปร b ให้ความสนใจกับการประกาศฟังก์ชัน doubler ซึ่งอยู่ที่จุดเริ่มต้นของโค้ดโปรแกรม: ระบุประเภทของพารามิเตอร์ฟังก์ชัน (i32) และประเภทของค่าส่งคืน (i32) หลังสัญลักษณ์ -> นอกจากนี้ยังง่ายที่จะเห็นว่าฟังก์ชันดำเนินการเพียงครั้งเดียว x * 2 ซึ่งไม่ได้ตามด้วยเครื่องหมายอัฒภาคเหมือนบล็อกปกติของโค้ด Rust เกิดอะไรขึ้นที่นั่น?

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

กลับไปที่ฟังก์ชัน main() โดยที่เราใช้มาโคร println!() เพื่อพิมพ์ผลลัพธ์ สังเกตเทคนิคการทดแทนค่าของตัวแปรโดยใช้ลำดับอักขระ () สุดท้าย ตัวอย่างนี้แสดงให้เห็นถึงคีย์เวิร์ด "match" ที่มีประโยชน์อย่างยิ่งของภาษาการเขียนโปรแกรม Rust ซึ่งสามารถลดจำนวนโค้ดลงได้อย่างมาก หากคุณต้องการดำเนินการคำสั่ง if/else จำนวนมาก ในกรณีนี้ 1...10 คือการประกาศช่วงของค่า (รวม 1 ถึง 10) และอักขระขีดล่าง (_) จะตรงกับค่าอื่นๆ ทั้งหมด

ใน Rust ประเภทสตริงอักขระอนุญาตให้ใช้อักขระสี่ไบต์นั่นคืออักขระ Unicode ใด ๆ และนั่นหมายความว่าภาษาการเขียนโปรแกรมได้รับการปรับในขั้นตอนการออกแบบให้ทำงานกับภาษาต่าง ๆ และ อักขระพิเศษ- ข้อมูลที่มีประโยชน์อีกประเภทหนึ่งคือ tuple ซึ่งเป็นชุดของตัวแปรประเภทต่างๆ:

ให้ x = (1, 2.0, "สวัสดี");

ในกรณีนี้ ค่าจำนวนเต็ม ค่าทศนิยม และค่าสตริงจะถูกวางไว้ในทูเพิลเดียวกัน ค่าเหล่านี้ไม่เปลี่ยนรูปและสามารถเข้าถึงได้ในลักษณะเดียวกัน:

Println!("()", x.2);

เป็นผลให้ค่าขององค์ประกอบที่สามของ tuple x จะถูกส่งออกนั่นคือสตริง "Hello" เช่นเดียวกับในกรณีของอาร์เรย์ปกติ ซึ่งได้รับการสนับสนุนใน Rust เช่นกัน การกำหนดหมายเลของค์ประกอบของสิ่งอันดับเริ่มต้นจากศูนย์ คุณสามารถใช้สิ่งอันดับเพื่อส่งกลับค่าหลายค่าจากฟังก์ชัน:

สวิตช์ Fn (อินพุต: (i32, i32)) -> (i32, i32) ( (input.1, input.0) ) fn main() ( ให้ x = (10, 50); ให้ y = สวิตช์(x) ; println!("(), ()", y.0, y.1 )

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

ฟังก์ชัน main() จะสร้างทูเปิลชื่อ x ซึ่งมีค่า 10 และ 50 และทูเพิลชื่อ y ที่มีค่าที่ส่งคืนจากการเรียกไปยังสวิตช์() จากนั้นค่าของทูเพิลก็จะแสดงบนหน้าจอ (50, 10)

คำแนะนำ:หากคุณต้องการสำรวจความสามารถของ Rust ด้วยตัวเอง เราขอแนะนำให้เริ่มต้นด้วยการอ่านเอกสารอย่างเป็นทางการที่ https://doc.rust-lang.org/book

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

ดังนั้นเราจึงอยากจะแนะนำให้คุณรู้จักกับเด็กชายวันเกิดคนล่าสุด (เขาอายุครบหนึ่งขวบเมื่อวันที่ 15 พฤษภาคม 2559) - สนิม นี่คือภาษาโปรแกรมสากลที่พัฒนาโดย Mozilla ซึ่งมีหลักการหลัก 3 ประการ ได้แก่ ความเร็ว ความปลอดภัย และการยศาสตร์ ผู้สร้างเองก็ถือว่าเป็นหนึ่งในผู้สืบทอด C/C++ ที่เป็นไปได้มากที่สุด จากการสำรวจในพอร์ทัล StackOverflow พบว่า Rust เป็นภาษาที่นักพัฒนาชื่นชอบมากที่สุดในปัจจุบัน เอาล่ะ เรามาดูกันดีกว่าว่ามันคืออะไร

สนิมสำหรับผู้เริ่มต้น

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

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

วิธีการศึกษา

คุณสามารถค้นหาเกือบทุกอย่างที่คุณต้องการได้จากเว็บไซต์อย่างเป็นทางการ นอกจากนี้ชุมชนของผู้ติดตาม Rust นั้นมีขนาดใหญ่และเป็นมิตรมาก ดังนั้นคุณสามารถติดต่อ IRC (มีส่วนภาษารัสเซีย) และฟอรัมอย่างเป็นทางการเพื่อขอคำแนะนำได้ตลอดเวลา นอกจากนี้ หนังสือต่างๆ รวมถึงหนังสืออิเล็กทรอนิกส์ก็เริ่มปรากฏให้เห็นทีละน้อย ยังคงเป็นเรื่องยากที่จะประเมินคุณภาพ แต่นี่คือข้อเท็จจริง

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

  • การประชุม RustConf วันที่ 9-10 กันยายนที่พอร์ตแลนด์ สหรัฐอเมริกา
  • 17 กันยายน การประชุมชุมชนยุโรป RustFest ที่กรุงเบอร์ลิน ประเทศเยอรมนี
  • 27 ตุลาคม การประชุมใหญ่ Rust Belt Rust ในเมืองพิตต์สเบิร์ก สหรัฐอเมริกา;

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

ลักษณะเฉพาะ

ทำซ้ำสิ่งที่กล่าวไว้ก่อนหน้านี้เล็กน้อยเราจะเน้นถึงข้อดีและข้อเสียหลักของภาษา Rust

ข้อดี:

  • ทำงานอย่างปลอดภัยด้วยหน่วยความจำ
  • ประสิทธิภาพสูง
  • ชนิดข้อมูลพีชคณิต
  • ความสามารถในการคาดการณ์ของการรวบรวม

จุดด้อย:

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

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

ความต้องการ

ปัจจุบัน Rust ได้รับความนิยมในหมู่นักพัฒนาเกม กราฟิก และระบบปฏิบัติการ อย่างไรก็ตาม ด้วยเหตุผลที่ชัดเจน จำนวนสถานที่นิ่งที่ต้องการผู้เชี่ยวชาญด้านสนิมที่เชี่ยวชาญสูงนั้นมีน้อยมากในโลกและมากกว่านั้นในรัสเซีย อย่างไรก็ตาม ยังไม่มีสัญญาณว่าภาษาจะจมสู่การลืมเลือน ดูเหมือนว่าจะเป็นการยึดครองโลกอย่างเป็นระบบมากกว่า ซึ่งหมายความว่าทักษะที่ดีในการใช้ Rust ในอนาคตจะช่วยให้คุณหางานที่น่าสนใจและรายได้ดีทั้งในประเทศของเราและต่างประเทศ

ยังคงเป็นที่ต้องการ: อาชีพ ""

ในปี 2013 Mozilla ร่วมกับ Samsung ได้ประกาศการพัฒนาเอนจิ้นเว็บเบราว์เซอร์ใหม่ Servo มันถูกสร้างขึ้นมาเพื่อโดยเฉพาะ โปรเซสเซอร์แบบมัลติคอร์ อุปกรณ์เคลื่อนที่สามารถแบ่งงานออกเป็นเธรดคู่ขนานและลดเวลาในการโหลดหน้าเว็บได้อย่างมาก เซอร์โวเขียนด้วยภาษาโปรแกรม Rust ทั้งหมด ซึ่ง Mozilla พัฒนาขึ้นเองเพื่อเขียนแอปพลิเคชันบนมือถือ

เกี่ยวกับภาษา

Rust เป็นภาษาโปรแกรมขั้นตอนที่รองรับรูปแบบการเขียนโค้ดที่หลากหลาย นักพัฒนา Graydon Hoare เริ่มสร้างภาษาในปี 2549 และสามปีต่อมา Mozilla ได้เข้าร่วมโครงการนี้ ในปี 2010 Rust ถูกนำเสนอในการประชุม Mozilla Summit ในปีเดียวกันนั้น การพัฒนาถูกถ่ายโอนไปยังคอมไพเลอร์ที่เขียนด้วยภาษา Rust คอมไพเลอร์ใช้ระบบการวิเคราะห์และการแปลงโปรแกรมสากล LLVM เป็นฐานข้อมูล

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

หัวใจของภาษาคือ Graydon Hoare ได้วางแนวคิดต่างๆ ไว้ดังนี้:

  • ความปลอดภัย. Rust มีข้อจำกัดของโปรแกรมเมอร์จำนวนหนึ่งที่เปิดใช้งานตามค่าเริ่มต้น หากต้องการปิดใช้งาน จำเป็นต้องมีป้ายกำกับ "ไม่ปลอดภัย" ในบล็อกและฟังก์ชัน
  • ความเร็ว. ภาษานี้เทียบได้ในด้านความเร็วกับภาษาการเขียนโปรแกรมอื่น C++ ซึ่งให้ข้อดีที่ชัดเจนหลายประการสำหรับโปรแกรมเมอร์
  • ความเท่าเทียม ระบบสามารถทำการคำนวณได้หลายอย่างพร้อมกัน และในขณะเดียวกันก็สามารถโต้ตอบซึ่งกันและกันได้
  • ความกะทัดรัด คำหลักคำแรกใน Rust ถูกจำกัดไว้ที่ห้าอักขระ แต่ต่อมาข้อจำกัดนี้ก็ถูกยกเลิก

ตัวอย่างของรหัสแรกๆ ใน Rust

อย่างไรก็ตาม Rust ไม่ได้มีข้อเสียใด ๆ เลย สิ่งที่โดดเด่นที่สุดคือ:

  • ความซ้ำซ้อนของรหัส
  • ขาดวรรณกรรมสำหรับการเรียนภาษา
  • ความชัดเจนในการป้อนพารามิเตอร์การคอมไพล์ สิ่งนี้ไม่เหมาะกับโปรแกรมเมอร์ที่มีประสบการณ์เสมอไปเนื่องจากภาษาอื่นไม่มีกฎที่คล้ายกัน

อย่างไรก็ตาม ภาษาได้รับการปรับปรุงและขยายให้ทันสมัยอยู่เสมอ: การอัปเดตจะออกทุกๆ 6 สัปดาห์

เปรียบเทียบสนิมกับ C ++

ผู้สร้าง Rust พิจารณาว่าเป็นภาษาที่สืบทอดมาจาก C ++ ซึ่งเกิดขึ้นในช่วงต้นทศวรรษ 1980 เมื่อนักพัฒนามีการปรับปรุงภาษา C หลายประการ ดังนั้นจึงคุ้มค่าที่จะเปรียบเทียบภาษาที่ยังเยาว์วัยและยังคงเปลี่ยนแปลงกับภาษาที่ผ่านการทดสอบตามเวลา

  • การเข้าถึงหน่วยความจำระยะไกล ในภาษา C++ การลบตัวแปรอาจทำให้เกิดปัญหาหลายประการ ภาวะแทรกซ้อนดังกล่าวไม่สามารถทำได้ใน Rust เนื่องจากไม่มีคำสั่งในการลบหน่วยความจำ คอมไพเลอร์สืบทอดจะรายงานว่าโค้ดที่คุณเขียนมีข้อผิดพลาด และคอมไพเลอร์ C++ จะแสดงผลลัพธ์โดยไม่มีค่าที่ถูกลบออก โดยไม่ต้องรายงานปัญหาด้วยซ้ำ
  • อัฒภาค. การเพิ่มอัฒภาคเพิ่มเติมให้กับโค้ดของคุณจะทำให้เกิดข้อผิดพลาดในภาษา C++ ในขณะที่ใน Rust ตัวลูปจะอยู่ในวงเล็บปีกกา
  • รหัสที่ไม่ปลอดภัย Rust มีป้ายกำกับ "ไม่ปลอดภัย" ที่แยกโค้ดหลักออกจากโค้ดที่ไม่ปลอดภัย ในอนาคต เมื่อตรวจสอบโค้ด การดำเนินการนี้จะช่วยให้คุณสามารถจำกัดการค้นหาช่องโหว่ให้แคบลงได้

Firefox ถูกนำมาใช้ในภาษา C++: ภาษาที่ไม่แน่นอนนี้ต้องการความใส่ใจในรายละเอียดเพิ่มมากขึ้น มิฉะนั้นข้อผิดพลาดจะกลายเป็นช่องโหว่ร้ายแรง สนิมได้รับการออกแบบมาเพื่อแก้ไขปัญหานี้

อนาคต

ในการจัดอันดับ RedMonk ในไตรมาสที่สามของปี 2018 ภาษาการเขียนโปรแกรม Mozilla อยู่ในอันดับที่ 23 อย่างต่อเนื่อง ผู้เชี่ยวชาญเชื่อว่าตำแหน่งของเขาไม่เสี่ยงต่อการพัฒนา อย่างไรก็ตาม ในเดือนสิงหาคม 2018 ผู้สร้างได้เปิดตัว Rust 1.28 ที่อัปเดตแล้ว

หลังจากการเปิดตัว Rust ในปี 2558 ตาม Stack Overflow นักพัฒนา 74% ต้องการทำความคุ้นเคยกับมัน อย่างไรก็ตาม ในปี 2559 มันได้ขยับขึ้นมาเป็นที่หนึ่ง: 79% ของผู้ใช้ยกให้ Rust เป็นภาษาโปรแกรมที่พวกเขาชื่นชอบ และแสดงความปรารถนาที่จะทำงานกับมันต่อไป สนิมเกิดขึ้นครั้งแรกในพารามิเตอร์นี้ในปี 2561

Stack Overflow เป็นระบบคำถามและคำตอบการเขียนโปรแกรมยอดนิยมที่พัฒนาขึ้นในปี 2551

ความนิยมของ Rust ได้รับการยืนยันจากจำนวนบริษัทที่ใช้มันในการพัฒนา ปัจจุบันรายชื่อนี้รวม 105 องค์กร

สนิมเป็นภาษาโปรแกรมทดลองใหม่ที่พัฒนาโดย Mozilla ภาษาได้รับการรวบรวมและมีหลายกระบวนทัศน์ ซึ่งเป็นทางเลือกแทน C/C++ ซึ่งในตัวมันเองก็น่าสนใจ เนื่องจากมีคู่แข่งไม่มากนักสำหรับการแข่งขัน คุณสามารถจำเพลง D ของ Walter Bright หรือ Go ของ Google ได้
Rust รองรับการเขียนโปรแกรมเชิงฟังก์ชัน แบบขนาน ขั้นตอน และเชิงวัตถุ เช่น กระบวนทัศน์เกือบทั้งหมดที่ใช้ในการเขียนโปรแกรมแอปพลิเคชันจริง

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

ความประทับใจครั้งแรก

ไวยากรณ์ของภาษาถูกสร้างขึ้นในรูปแบบคล้าย C แบบดั้งเดิม (ซึ่งเป็นข่าวดี เนื่องจากนี่เป็นมาตรฐานโดยพฤตินัยอยู่แล้ว) โดยปกติแล้ว ข้อผิดพลาดในการออกแบบ C/C++ ที่รู้จักกันดีได้ถูกนำมาพิจารณาด้วย
Hello World แบบดั้งเดิมมีลักษณะดังนี้:
ใช้มาตรฐาน; fn main(args: ) ( std::io::println("hello world from " + args + "!"); )

ตัวอย่างที่ซับซ้อนกว่าเล็กน้อย - ฟังก์ชันการคำนวณแฟกทอเรียล:

Fn fac(n: int) -> int ( ให้ผลลัพธ์ = 1, i = 1; ในขณะที่ i<= n { result *= i; i += 1; } ret result; }

ดังที่คุณเห็นจากตัวอย่าง ฟังก์ชันต่างๆ ได้รับการประกาศในรูปแบบ "ใช้งานได้" (รูปแบบนี้มีข้อดีบางประการเหนือ "int fac(int n)") แบบดั้งเดิม เราเห็น การอนุมานประเภทอัตโนมัติ(let คีย์เวิร์ด) ไม่มีวงเล็บในอาร์กิวเมนต์ while (เหมือนกับ Go) อีกสิ่งหนึ่งที่ดึงดูดสายตาคุณได้ทันทีคือความกะทัดรัดของคำหลัก ผู้สร้าง Rust พยายามรักษาคีย์เวิร์ดทั้งหมดให้สั้นที่สุดเท่าที่จะเป็นไปได้ และบอกตามตรงว่าฉันชอบมัน

คุณสมบัติทางวากยสัมพันธ์ขนาดเล็ก แต่น่าสนใจ

  • คุณสามารถแทรกขีดล่างลงในค่าคงที่ตัวเลขได้ นี่เป็นคุณสมบัติที่มีประโยชน์ ขณะนี้คุณสมบัตินี้ถูกเพิ่มเข้าไปในภาษาใหม่หลายภาษา
    0xffff_ffff_ffff_ffff_ffff_ffff
  • ค่าคงที่ไบนารี แน่นอนว่าโปรแกรมเมอร์ตัวจริงต้องแปลง bin เป็น hex ในหัวของเขา แต่วิธีนี้จะสะดวกกว่า! 0b1111_1111_1001_0000
  • เนื้อความของข้อความใดๆ (แม้จะประกอบด้วยนิพจน์เดียวก็ตาม) จะต้องอยู่ในเครื่องหมายปีกกา ตัวอย่างเช่น ในภาษา C คุณสามารถเขียน if(x>0) foo(); ใน Rust คุณต้องใส่เครื่องหมายปีกการอบ foo()
  • แต่อาร์กิวเมนต์ของ if, while และตัวดำเนินการที่คล้ายกันไม่จำเป็นต้องอยู่ในวงเล็บ
  • ในหลายกรณี กลุ่มของโค้ดอาจถือเป็นนิพจน์ได้ โดยเฉพาะสิ่งต่อไปนี้เป็นไปได้:
    ให้ x = ถ้า the_stars_align() ( 4 ) else if some_else() ( 3 ) else ( 0 );
  • ไวยากรณ์การประกาศฟังก์ชัน - อันดับแรกคือคีย์เวิร์ด fn จากนั้นรายการอาร์กิวเมนต์ ประเภทของอาร์กิวเมนต์จะถูกระบุหลังชื่อ จากนั้นหากฟังก์ชันส่งคืนค่า ลูกศร "->" และประเภทของค่าที่ส่งคืน
  • ตัวแปรจะถูกประกาศในลักษณะเดียวกัน: คำสำคัญ ให้ ชื่อของตัวแปร หลังจากตัวแปร คุณสามารถระบุประเภทผ่านโคลอน จากนั้นจึงกำหนดค่าเริ่มต้น
    ให้นับ: int = 5;
  • โดยค่าเริ่มต้น ตัวแปรทั้งหมดจะไม่เปลี่ยนรูป คีย์เวิร์ดที่ไม่แน่นอนใช้ในการประกาศตัวแปรที่ไม่แน่นอน
  • ชื่อ ประเภทพื้นฐาน- กะทัดรัดที่สุดในบรรดาทั้งหมดที่ฉันเคยพบ: i8, i16, i32, i64, u8, u16, u32, u64,f32, f64
  • ตามที่กล่าวไว้ข้างต้น รองรับการอนุมานประเภทอัตโนมัติ
ภาษามีเครื่องมือแก้ไขข้อบกพร่องโปรแกรมในตัว:
คำสำคัญ ล้มเหลวสิ้นสุดกระบวนการปัจจุบัน
คำสำคัญ บันทึกส่งออกนิพจน์ภาษาใด ๆ ไปยังบันทึก (เช่น ไปยัง stderr)
คำสำคัญ ยืนยันตรวจสอบนิพจน์และหากเป็นเท็จ ให้ยุติกระบวนการปัจจุบัน
คำสำคัญ บันทึกช่วยให้คุณสามารถแสดงข้อมูลเพิ่มเติมในกรณีที่กระบวนการยุติอย่างผิดปกติ

ประเภทข้อมูล

Rust เช่นเดียวกับ Go รองรับ การพิมพ์โครงสร้าง(แม้ว่าตามที่ผู้เขียนระบุ ภาษาจะพัฒนาอย่างอิสระ ดังนั้นนี่คืออิทธิพลของบรรพบุรุษร่วมกันของพวกเขา - Alef, Limbo ฯลฯ ) การพิมพ์แบบโครงสร้างคืออะไร? ตัวอย่างเช่น คุณมีโครงสร้างที่ประกาศไว้ในไฟล์บางไฟล์ (หรือในคำศัพท์เฉพาะของ Rust เรียกว่า “บันทึก”)
พิมพ์ point = (x: float, y: float);
คุณสามารถประกาศตัวแปรและฟังก์ชันต่างๆ ด้วยประเภทอาร์กิวเมนต์ "point" จากนั้น ที่อื่น คุณสามารถประกาศโครงสร้างอื่นๆ บางอย่างได้ เช่น
พิมพ์ MySuperPoint = (x: float, y: float);
และตัวแปรประเภทนี้จะเข้ากันได้อย่างสมบูรณ์ด้วย ตัวแปรประเภทจุด.

ในทางตรงกันข้าม การพิมพ์แบบเสนอชื่อที่ใช้ใน C, C++, C# และ Java ไม่อนุญาตให้ใช้โครงสร้างดังกล่าว ด้วยการพิมพ์แบบเสนอชื่อ แต่ละโครงสร้างจะเป็นประเภทที่ไม่ซ้ำกัน ซึ่งเข้ากันไม่ได้โดยค่าเริ่มต้นกับประเภทอื่นๆ

โครงสร้างใน Rust เรียกว่า "บันทึก" นอกจากนี้ยังมีสิ่งอันดับ - เป็นระเบียนเดียวกัน แต่มีฟิลด์ที่ไม่ระบุชื่อ องค์ประกอบทูเปิลไม่สามารถเปลี่ยนแปลงได้ ซึ่งต่างจากองค์ประกอบของบันทึก

มีเวกเตอร์ - ในบางวิธีคล้ายกับอาร์เรย์ทั่วไป และในบางวิธีคล้ายกับประเภท std::vector จาก stl เมื่อเริ่มต้นด้วยรายการ จะใช้วงเล็บเหลี่ยม ไม่ใช่วงเล็บปีกกาเหมือนใน C/C++

ให้ myvec = ;

อย่างไรก็ตาม เวกเตอร์เป็นโครงสร้างข้อมูลแบบไดนามิก โดยเฉพาะอย่างยิ่ง เวกเตอร์รองรับการต่อข้อมูล

ให้ v: mutable = ; วี += ;

มีแม่แบบ. ไวยากรณ์ของพวกเขาค่อนข้างสมเหตุสมผล โดยไม่มี "เทมเพลต" จาก C++ ยุ่งเหยิง รองรับเทมเพลตฟังก์ชันและประเภทข้อมูล

Fn สำหรับ_rev (v: [T], act: block(T)) ( ให้ i = std::vec::len(v); ในขณะที่ i > 0u ( i -= 1u; act(v[i]); ) ) พิมพ์ วงกลม_buf = (เริ่มต้น: uint, สิ้นสุด: uint, buf: );

ภาษารองรับสิ่งที่เรียกว่า แท็ก- นี่ไม่ใช่อะไรมากไปกว่าสหภาพจาก C โดยมีฟิลด์เพิ่มเติม - รหัสของตัวแปรที่ใช้ (นั่นคือบางสิ่งที่เหมือนกันระหว่างสหภาพและการแจงนับ) หรือจากมุมมองทางทฤษฎี ชนิดข้อมูลพีชคณิต

รูปร่างแท็ก ( วงกลม(จุด, ลอย); สี่เหลี่ยมผืนผ้า(จุด, จุด); )

ในกรณีที่ง่ายที่สุด แท็กจะเหมือนกับการแจงนับ:

แท็กสัตว์ ( dog; cat; ) ให้ a: animal = dog; ก = แมว;
ในกรณีที่ซับซ้อนมากขึ้น แต่ละองค์ประกอบของ "การแจงนับ" จะเป็นโครงสร้างอิสระที่มี "ตัวสร้าง" ของตัวเอง
อีกตัวอย่างที่น่าสนใจคือโครงสร้างแบบเรียกซ้ำที่ใช้ในการกำหนดวัตถุประเภท "รายการ":
รายการแท็ก ( ไม่มี; ข้อเสีย (T, @list - ) ให้: รายการ = ข้อเสีย(10, @cons(12, @ไม่มี));
แท็กสามารถมีส่วนร่วมในนิพจน์การจับคู่รูปแบบ ซึ่งอาจค่อนข้างซับซ้อน
alt x ( cons(a, @cons(b, _)) ( process_pair(a,b); ) cons(10, _) ( process_ten(); ) _ ( ล้มเหลว; ) )

การจับคู่รูปแบบ

ประการแรก เราสามารถพิจารณารูปแบบการจับคู่เป็นสวิตช์ที่ได้รับการปรับปรุง มีการใช้คีย์เวิร์ด alt ตามด้วยนิพจน์ที่กำลังวิเคราะห์ จากนั้นในเนื้อหาของคำสั่ง - รูปแบบและการดำเนินการหากรูปแบบตรงกัน
alt my_number ( 0 ( std::io::println("zero"); ) 1 | 2 ( std::io::println("one or two"); ) 3 ถึง 10 ( std::io::println ("สามถึงสิบ"); ) _ ( std::io::println("อย่างอื่น"); ) )
ในฐานะ “รูปแบบ” คุณไม่เพียงแต่ใช้ค่าคงที่ (เช่นใน C) เท่านั้น แต่ยังสามารถใช้นิพจน์ที่ซับซ้อนมากขึ้นด้วย เช่น ตัวแปร สิ่งอันดับ ช่วง ประเภท ตัวยึดตำแหน่ง ("_") คุณสามารถระบุเงื่อนไขเพิ่มเติมได้โดยใช้คำสั่ง when ที่ตามหลังรูปแบบทันที มีโอเปอเรเตอร์รูปแบบพิเศษสำหรับการจับคู่ประเภท สิ่งนี้เป็นไปได้เนื่องจากภาษามีประเภทตัวแปรสากล ใดๆซึ่งวัตถุสามารถมีค่าประเภทใดก็ได้

พอยน์เตอร์นอกเหนือจากตัวชี้ "C" ตามปกติแล้ว Rust ยังสนับสนุนตัวชี้ "อัจฉริยะ" พิเศษที่มีการนับอ้างอิงในตัว - แชร์ (กล่องที่ใช้ร่วมกัน) และไม่ซ้ำกัน (กล่องเฉพาะ) ค่อนข้างคล้ายกับ shared_ptr และ Unique_ptr จาก C++ พวกเขามีไวยากรณ์ของตัวเอง: @ สำหรับแชร์ และ ~ สำหรับค่าไม่ซ้ำกัน สำหรับพอยน์เตอร์เฉพาะ แทนที่จะคัดลอก มีการดำเนินการพิเศษ - การย้าย:
ให้ x = ~10; ปล่อยให้คุณ<- x;
หลังจากการเคลื่อนไหวดังกล่าว ตัวชี้ x จะถูกกำหนดค่าเริ่มต้น

การปิด แอปพลิเคชันบางส่วน ตัววนซ้ำ

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

1. คำสำคัญ แลมบ์ดาใช้เพื่อประกาศฟังก์ชันที่ซ้อนกันหรือประเภทข้อมูลการทำงาน

Fn make_plus_function(x: int) -> lambda(int) -> int ( lambda(y: int) -> int ( x + y ) ) ให้ plus_two = make_plus_function(2); ยืนยัน plus_two(3) == 5;

ในตัวอย่างนี้ เรามีฟังก์ชัน make_plus_function ที่รับหนึ่งอาร์กิวเมนต์ "x" ประเภท int และส่งกลับฟังก์ชันประเภท "int->int" (lambda คือคีย์เวิร์ดที่นี่) เนื้อหาของฟังก์ชันจะอธิบายฟังก์ชันนี้เอง การไม่มีตัวดำเนินการ "ส่งคืน" ทำให้เกิดความสับสนเล็กน้อย แต่นี่เป็นเรื่องปกติสำหรับ FP

2. คำสำคัญ ปิดกั้นใช้ในการประกาศประเภทการทำงาน - อาร์กิวเมนต์ของฟังก์ชัน ซึ่งสามารถถูกแทนที่ด้วยสิ่งที่คล้ายกับบล็อกของโค้ดปกติ
fn map_int(f: block(int) -> int, vec: ) -> ( ให้ผลลัพธ์ = ; สำหรับฉันใน vec ( ผลลัพธ์ += ; ) ret result; ) map_int((|x| x + 1 ), );

ที่นี่เรามีฟังก์ชันที่อินพุตเป็นบล็อก โดยพื้นฐานแล้วคือฟังก์ชันแลมบ์ดาประเภท “int->int” และเวกเตอร์ประเภท int (เพิ่มเติมเกี่ยวกับไวยากรณ์ของเวกเตอร์ในภายหลัง) ตัว “block” นั้นเขียนด้วยรหัสการโทรโดยใช้ไวยากรณ์ที่ค่อนข้างผิดปกติ (|x| x + 1) โดยส่วนตัวแล้วฉันชอบ lambdas ในภาษา C# ซึ่งเป็นสัญลักษณ์ | ถูกมองว่าเป็นแบบ bitwise OR อย่างต่อเนื่อง (ซึ่งมีอยู่ใน Rust เช่นกัน เช่นเดียวกับการดำเนินการที่ใช้ C แบบเก่าทั้งหมด)

3. แอปพลิเคชันบางส่วนคือการสร้างฟังก์ชันตามฟังก์ชันอื่นที่มีอาร์กิวเมนต์มากขึ้นโดยการระบุค่าของอาร์กิวเมนต์บางส่วนของฟังก์ชันอื่นนั้น คำสำคัญที่ใช้สำหรับสิ่งนี้คือ ผูกและอักขระตัวยึดตำแหน่ง "_":

ให้ daynum = ผูก std::vec::position(_, ["mo", "tu", "we", "do", "fr", "sa", "su"])

เพื่อให้ชัดเจนยิ่งขึ้น ฉันจะบอกทันทีว่าสามารถทำได้ใน C ปกติโดยการสร้าง wrapper ง่ายๆ บางอย่างเช่นนี้:
const char* daynum (int i) ( const char *s =("mo", "tu", "เรา", "ทำ", "fr", "sa", "su"); กลับ s[i]; )

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

อีกตัวอย่างหนึ่ง: ฟังก์ชัน add ได้รับการประกาศพร้อมกับอาร์กิวเมนต์ int สองตัว โดยส่งคืน int ถัดไป จะมีการประกาศประเภทการทำงาน single_param_fn ซึ่งมีหนึ่งอาร์กิวเมนต์ int และส่งกลับ int เมื่อใช้การผูก จะมีการประกาศออบเจ็กต์ฟังก์ชันสองรายการ add4 และ add5 สร้างขึ้นบนพื้นฐานของฟังก์ชัน add ซึ่งมีการระบุอาร์กิวเมนต์บางส่วน

Fn เพิ่ม(x: int, y: int) -> int ( ret x + y; ) พิมพ์ single_param_fn = fn(int) -> int; ให้ add4: single_param_fn = ผูก เพิ่ม (4, _); ให้ add5: single_param_fn = ผูกเพิ่ม (_, 5);

วัตถุฟังก์ชันสามารถเรียกได้ในลักษณะเดียวกับ ฟังก์ชั่นปกติ.
ยืนยัน (เพิ่ม(4,5) == เพิ่ม4(5)); ยืนยัน (เพิ่ม(4,5) == เพิ่ม5(4));

4. ฟังก์ชันและเพรดิเคตล้วนๆ
ฟังก์ชัน Pure คือฟังก์ชันที่ไม่มีผลข้างเคียง (รวมถึงฟังก์ชันที่ไม่เรียกใช้ฟังก์ชันอื่นใดยกเว้นฟังก์ชัน Pure) ฟังก์ชันดังกล่าวระบุด้วยคีย์เวิร์ดที่บริสุทธิ์
บริสุทธิ์ fn lt_42(x: int) -> บูล ( ret (x< 42); }
เพรดิเคตเป็นฟังก์ชันล้วนๆ ที่ส่งคืนบูลประเภท ฟังก์ชันดังกล่าวสามารถใช้ได้ในระบบ typestate (ดูด้านล่าง) ซึ่งเรียกว่าในขั้นตอนการคอมไพล์สำหรับการตรวจสอบสแตติกต่างๆ

มาโครวากยสัมพันธ์
คุณลักษณะที่วางแผนไว้ แต่มีประโยชน์มาก มันยังอยู่ในช่วงเริ่มต้นของการพัฒนาใน Rust
std::io::println(#fmt("%s คือ %d", "คำตอบ", 42));
นิพจน์ที่คล้ายกับ printf ของ C แต่ดำเนินการในเวลาคอมไพล์ (ดังนั้น ข้อผิดพลาดอาร์กิวเมนต์ทั้งหมดจะถูกตรวจพบในขั้นตอนการคอมไพล์) น่าเสียดายที่มาโครวากยสัมพันธ์มีเนื้อหาน้อยมากและยังอยู่ระหว่างการพัฒนา แต่ก็หวังว่าจะมีบางอย่างเช่นมาโคร Nemerle ออกมา
อย่างไรก็ตาม ตรงกันข้ามกับ Nemerle ตัวเดียวกัน ฉันถือว่าการตัดสินใจเน้นมาโครทางวากยสัมพันธ์โดยใช้สัญลักษณ์ # เพื่อให้ฉลาดมาก: แมโครเป็นเอนทิตีที่แตกต่างจากฟังก์ชันมากและฉันคิดว่าสิ่งสำคัญคือต้องดูที่ แวบแรกว่าฟังก์ชันโค้ดถูกเรียกใช้ที่ไหนและที่ไหน - มาโคร

คุณสมบัติ

แนวคิดที่คล้ายกับแอตทริบิวต์ C# (และถึงแม้จะมีไวยากรณ์ที่คล้ายคลึงกัน) ขอขอบคุณเป็นพิเศษสำหรับนักพัฒนาสำหรับสิ่งนี้ ตามที่คุณคาดหวัง แอตทริบิวต์จะเพิ่มข้อมูลเมตาให้กับเอนทิตีที่พวกเขาใส่คำอธิบายประกอบ
# fn register_win_service() ( /* ... */ )
ไวยากรณ์แอตทริบิวต์อีกรูปแบบหนึ่งได้ถูกประดิษฐ์ขึ้น - บรรทัดเดียวกัน แต่มีเครื่องหมายอัฒภาคต่อท้าย อธิบายบริบทปัจจุบัน นั่นคือสิ่งที่สอดคล้องกับสิ่งที่ใกล้เคียงที่สุด วงเล็บปีกกาครอบคลุมคุณลักษณะดังกล่าว
fn register_win_service() ( #; /* ... */ )

คอมพิวเตอร์แบบขนาน

บางทีอาจเป็นส่วนที่น่าสนใจที่สุดของภาษา ขณะเดียวกันในบทช่วยสอนเรื่อง ในขณะนี้ไม่ได้อธิบายเลย :)
โปรแกรม Rust ประกอบด้วย "แผนผังงาน" แต่ละงานมีฟังก์ชันอินพุต, สแต็กของตัวเอง, วิธีการโต้ตอบกับงานอื่น ๆ - ช่องทางสำหรับข้อมูลขาออกและพอร์ตสำหรับข้อมูลขาเข้า และเป็นเจ้าของวัตถุบางส่วนในฮีปแบบไดนามิก
งาน Rust หลายรายการสามารถมีได้ภายในกระบวนการเดียว ระบบปฏิบัติการ- งาน Rust นั้น "มีน้ำหนักเบา": แต่ละงานใช้หน่วยความจำน้อยกว่ากระบวนการของ OS และการสลับระหว่างงานเหล่านั้นเร็วกว่าการสลับระหว่างกระบวนการของ OS (ในที่นี้ เราอาจหมายถึง "เธรด" ในที่สุด)

งานประกอบด้วยอย่างน้อยหนึ่งฟังก์ชันที่ไม่มีข้อโต้แย้ง งานนี้เปิดตัวโดยใช้ฟังก์ชันวางไข่ แต่ละงานสามารถมีช่องทางในการส่งข้อมูลไปยังงานอื่นได้ ช่องเป็นประเภทเทมเพลตพิเศษ chan ซึ่งกำหนดพารามิเตอร์ตามประเภทข้อมูลช่อง ตัวอย่างเช่น chan เป็นช่องทางในการส่งไบต์ที่ไม่ได้ลงนาม
หากต้องการส่งไปยังช่องสัญญาณ ให้ใช้ฟังก์ชัน send อาร์กิวเมนต์แรกคือช่อง และอาร์กิวเมนต์ที่สองคือค่าที่จะส่ง ฟังก์ชันนี้จะวางค่าลงในบัฟเฟอร์ภายในของช่องสัญญาณ
พอร์ตใช้ในการรับข้อมูล พอร์ตเป็นประเภทพอร์ตทั่วไปที่กำหนดพารามิเตอร์ตามประเภทข้อมูลพอร์ต: พอร์ตคือพอร์ตสำหรับรับไบต์ที่ไม่ได้ลงนาม
หากต้องการอ่านจากพอร์ต จะใช้ฟังก์ชัน recv อาร์กิวเมนต์คือพอร์ต และค่าที่ส่งคืนคือข้อมูลจากพอร์ต การอ่านขัดขวางงาน เช่น หากพอร์ตว่างเปล่า งานจะเข้าสู่สถานะรอจนกว่างานอื่นจะส่งข้อมูลไปยังช่องทางที่เกี่ยวข้องกับพอร์ต
การเชื่อมโยงช่องสัญญาณกับพอร์ตนั้นง่ายมาก - โดยการเริ่มต้นช่องสัญญาณด้วยพอร์ตโดยใช้คีย์เวิร์ด chan:
ให้ reqport = port();
ให้ reqchan = chan(reqport);
สามารถเชื่อมต่อหลายช่องสัญญาณเข้ากับพอร์ตเดียวได้ แต่ไม่สามารถเชื่อมต่อช่องสัญญาณหนึ่งเข้ากับพอร์ตหลาย ๆ พอร์ตพร้อมกันได้

พิมพ์สถานะ

ฉันไม่พบคำแปลที่เป็นที่ยอมรับโดยทั่วไปของแนวคิด "typestate" เป็นภาษารัสเซีย ดังนั้นฉันจะเรียกมันว่า "type state" สาระสำคัญของคุณลักษณะนี้คือ นอกเหนือจากการตรวจสอบประเภทปกติที่ใช้ในการพิมพ์แบบคงที่แล้ว ยังสามารถตรวจสอบบริบทเพิ่มเติมได้ในขั้นตอนการคอมไพล์อีกด้วย
ในรูปแบบใดรูปแบบหนึ่ง สถานะประเภทเป็นที่คุ้นเคยสำหรับโปรแกรมเมอร์ทุกคน - ตามข้อความของคอมไพเลอร์ "ตัวแปรถูกใช้โดยไม่ต้องเริ่มต้น" คอมไพเลอร์ตรวจพบตำแหน่งที่มีการอ่านตัวแปรที่ไม่เคยเขียนและออกคำเตือน มากขึ้น มุมมองทั่วไปแนวคิดจะเป็นดังนี้: วัตถุทุกชิ้นมีชุดของสถานะที่สามารถสันนิษฐานได้ แต่ละรัฐกำหนดการดำเนินการที่ถูกต้องและไม่ถูกต้องสำหรับวัตถุนั้น และคอมไพลเลอร์สามารถตรวจสอบได้ว่าอนุญาตให้มีการดำเนินการเฉพาะกับอ็อบเจ็กต์ในตำแหน่งใดตำแหน่งหนึ่งในโปรแกรมหรือไม่ สิ่งสำคัญคือต้องดำเนินการตรวจสอบเหล่านี้ในเวลารวบรวม

ตัวอย่างเช่น หากเรามีวัตถุประเภท "ไฟล์" ก็อาจมีสถานะเป็น "ปิด" และ "เปิด" และไม่อนุญาตให้ดำเนินการอ่านจากไฟล์หากไฟล์ถูกปิด ในภาษาสมัยใหม่ เป็นเรื่องปกติที่ฟังก์ชัน read จะส่งข้อยกเว้นหรือส่งคืนรหัสข้อผิดพลาด ระบบสถานะประเภทสามารถตรวจจับข้อผิดพลาดดังกล่าวได้ในขณะคอมไพล์ - เช่นเดียวกับที่คอมไพเลอร์กำหนดว่าการดำเนินการอ่านบนตัวแปรเกิดขึ้นก่อนการดำเนินการเขียนที่เป็นไปได้ใด ๆ ก็อาจระบุได้ว่าวิธีการ "อ่าน" นั้นใช้ได้ในสถานะ "เปิดไฟล์" ถูกเรียกก่อนเมธอด "เปิด" ซึ่งจะถ่ายโอนอ็อบเจ็กต์ไปยังสถานะนี้

Rust มีแนวคิดของ "เพรดิเคต" ซึ่งเป็นฟังก์ชันพิเศษที่ไม่มีผลข้างเคียงและส่งคืนประเภทบูล คอมไพเลอร์สามารถใช้ฟังก์ชันดังกล่าวเพื่อเรียกในขั้นตอนการคอมไพล์เพื่อวัตถุประสงค์ในการตรวจสอบคงที่ของเงื่อนไขบางประการ

ข้อจำกัดคือการตรวจสอบพิเศษที่สามารถทำได้ในเวลาคอมไพล์ คีย์เวิร์ดตรวจสอบใช้สำหรับสิ่งนี้
fn บริสุทธิ์ is_less_than (int a, int b) -< bool { ret a < b; } fn test() { let x: int = 10; let y: int = 20; check is_less_than(x,y); }
เพรดิเคตสามารถ "หยุด" บนพารามิเตอร์อินพุตของฟังก์ชันในลักษณะนี้:
การทดสอบ fn(int x, int y) : is_less_than(x,y) ( ... )

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

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

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

เมื่อเร็วๆ นี้ชุมชน Rust ได้มุ่งเน้นไปที่ความพยายามอย่างมากกับ I/O แบบอะซิงโครนัส ซึ่งนำไปใช้ในรูปแบบของห้องสมุด Tokio และนั่นก็ยอดเยี่ยมมาก

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

  • มันคืออะไร - อะซิงก์ I/O?
  • โครูทีนคืออะไร? โครูทีน )?
  • เธรดน้ำหนักเบาคืออะไร ( ด้ายน้ำหนักเบา )?
  • ฟิวเจอร์สคืออะไร?( ฟิวเจอร์ส )?

  • พวกเขาเข้ากันได้อย่างไร?

ฉันจะแสดงวิธีเขียนโปรแกรมขนาดเล็กที่ดาวน์โหลดฟีด ( ให้อาหาร) ในรูปแบบ JSON จะแยกวิเคราะห์และแสดงรายการบันทึกย่อไปยังคอนโซลในรูปแบบที่จัดรูปแบบ

สำหรับเรา ทุกอย่างส่งผลให้มีโค้ดที่กระชับมาก ยังไง? ดูใต้บาดแผล

คำหลักที่ไม่ปลอดภัยเป็นส่วนสำคัญของการออกแบบภาษาสนิม สำหรับผู้ที่ไม่คุ้นเคย คำสำคัญที่ไม่ปลอดภัยคือวิธีการเลี่ยงการตรวจสอบประเภท ( การตรวจสอบประเภท) สนิม

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

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

หมายเหตุนี้จะแนะนำคำหลักที่ไม่ปลอดภัยและแนวคิดของ "ความไม่ปลอดภัย" ที่จำกัด อันที่จริงนี่เป็นลางสังหรณ์ของบันทึกที่ฉันหวังว่าจะเขียนในภายหลัง เธอกล่าวถึงโมเดลหน่วยความจำของ Rust ซึ่งระบุสิ่งที่ทำได้และไม่สามารถทำได้ในโค้ดที่ไม่ปลอดภัย

เนื่องจากยังใหม่กับ Rust ฉันรู้สึกสับสน ในรูปแบบต่างๆการแสดงสตริง หนังสือเกี่ยวกับภาษาสนิมมีบทหนึ่งชื่อ References and Borrowing ซึ่งใช้สามบท ประเภทต่างๆตัวแปรสตริงในตัวอย่าง: String , &String และ &str

เริ่มจากความแตกต่างระหว่าง str และ String กันก่อน: String เป็นโครงสร้างข้อมูลที่ขยายได้และจัดสรรเป็นฮีป ในขณะที่ str เป็นสตริงที่มีความยาวคงที่ไม่เปลี่ยนรูป ที่ไหนสักแห่งในความทรงจำ

โปรแกรมเมอร์หลายคนรู้วิธีการเขียนโปรแกรมในภาษาเชิงวัตถุอยู่แล้ว Rust ไม่ใช่ภาษาเชิงวัตถุแบบคลาสสิก แต่สามารถใช้เครื่องมือ OOP พื้นฐานได้

ในบทความนี้ เราจะดูวิธีการเขียนโปรแกรมใน Rust ในรูปแบบ OOP เราจะทำเช่นนี้โดยใช้ตัวอย่าง: เราจะสร้างลำดับชั้นของชั้นเรียนในงานการฝึกอบรม

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

Rust เป็นภาษาที่หรูหราซึ่งค่อนข้างแตกต่างจากภาษายอดนิยมอื่นๆ มากมาย ตัวอย่างเช่น แทนที่จะใช้คลาสและการสืบทอด Rust เสนอระบบประเภทตามลักษณะของตัวเอง อย่างไรก็ตาม ฉันเชื่อว่าโปรแกรมเมอร์หลายคนที่เริ่มรู้จักกับ Rust (เช่นฉัน) ไม่คุ้นเคยกับรูปแบบการออกแบบที่เป็นที่ยอมรับโดยทั่วไป

ในบทความนี้ ฉันต้องการหารือเกี่ยวกับรูปแบบการออกแบบ ชนิดใหม่(ประเภทใหม่) รวมถึงลักษณะจากและเข้าสู่ซึ่งช่วยในการแปลงประเภท

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

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

รูปแบบหนึ่งที่น่าสนใจซึ่งมักนำไปใช้กับปัญหาดังกล่าวคือ "เครื่องสถานะจำกัด" ฉันขอแนะนำให้ใช้เวลาสักหน่อยเพื่อทำความเข้าใจว่าวลีนี้หมายความว่าอย่างไร และเหตุใดจึงน่าสนใจมาก

ด้านล่างนี้เป็นคำอธิบายแบบกราฟิกของการย้าย การคัดลอก และการยืมในภาษาโปรแกรม Rust โดยพื้นฐานแล้ว แนวคิดเหล่านี้มีความเฉพาะเจาะจงสำหรับ Rust และมักจะเป็นอุปสรรคสำหรับมือใหม่

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

การใช้เลขคณิตธรรมชาติโดยใช้ตัวเลข Peano ถือเป็นงานยอดนิยมในการสอนการเขียนโปรแกรม ฉันสงสัยว่าเป็นไปได้หรือไม่ที่จะนำไปใช้ใน Rust

ดังนั้น งานของฉันคือจดและเพิ่มตัวเลขธรรมชาติพร้อมกับการตรวจสอบประเภท

ตามวิกิพีเดีย “สัจพจน์ของ Peano เป็นหนึ่งในระบบของสัจพจน์สำหรับจำนวนธรรมชาติ ซึ่งนำมาใช้ในศตวรรษที่ 19 โดยนักคณิตศาสตร์ชาวอิตาลี Giuseppe Peano”

เราสนใจสองรายการ - ซึ่งคุณสามารถป้อนและใช้ตัวเลขธรรมชาติได้:

  • 1 เป็นจำนวนธรรมชาติ
  • จำนวนที่อยู่หลังจำนวนธรรมชาติก็เป็นจำนวนธรรมชาติเช่นกัน

มาเขียนคำต่อคำด้วยสนิมโดยใช้:

1 2 3 4 enum Nat(ศูนย์, Succ(Nat))

Nat เป็นศูนย์หรือจำนวนธรรมชาติถัดไป

ความคิดเห็น: โครงการ Futures-rs ได้รับการจัดระเบียบใหม่และเปลี่ยนชื่อหลายอย่าง หากเป็นไปได้ ลิงก์จะได้รับการอัปเดต

เริ่มต้นกับอนาคต

เอกสารนี้จะช่วยคุณสำรวจคอนเทนเนอร์ภาษาการเขียนโปรแกรมฟิวเจอร์สสำหรับ Rust ซึ่งให้การใช้งานฟิวเจอร์สและเธรดโดยไม่มีค่าใช้จ่าย Futures มีให้บริการในภาษาการเขียนโปรแกรมอื่นๆ มากมาย เช่น C++, Java และ Scala และ Futures Container ได้รับแรงบันดาลใจจากไลบรารีของภาษาเหล่านี้ อย่างไรก็ตาม มันเป็นไปตามหลักสรีรศาสตร์และยังยึดมั่นในปรัชญานามธรรมแบบไม่มีค่าใช้จ่ายที่มีอยู่ใน Rust กล่าวคือ: ไม่จำเป็นต้องมีการจัดสรรหน่วยความจำเพื่อสร้างและเขียนอนาคต และจำเป็นต้องมีการจัดสรรเพียงครั้งเดียวสำหรับงานที่จัดการพวกมัน ฟิวเจอร์สมีจุดมุ่งหมายเพื่อเป็นพื้นฐานสำหรับ I/O แบบอะซิงโครนัสที่ประกอบได้และมีประสิทธิภาพสูงใน Rust และการวัดประสิทธิภาพในช่วงแรกแสดงให้เห็นว่าเซิร์ฟเวอร์ HTTP แบบธรรมดาที่สร้างขึ้นบนฟิวเจอร์สนั้นรวดเร็วจริงๆ

เอกสารนี้แบ่งออกเป็นหลายส่วน:

  • "สวัสดีชาวโลก!";
  • ประเภทอนาคต
  • พิมพ์ กระแส ;
  • ฟิวเจอร์สและสตรีมเฉพาะ (สตรีม);
  • กลับฟิวเจอร์ส;
  • งานและอนาคต
  • ข้อมูลงานท้องถิ่น

ความคิดเห็น: โครงการ Futures-rs ได้รับการจัดระเบียบใหม่และเปลี่ยนชื่อหลายอย่าง หากเป็นไปได้ ลิงก์จะได้รับการอัปเดต

ช่องว่างสำคัญประการหนึ่งในระบบนิเวศของ Rust คือความรวดเร็วและมีประสิทธิภาพ I/O แบบอะซิงโครนัส- เรามีรากฐานที่มั่นคงจากไลบรารี mio แต่เป็นระดับที่ต่ำมาก: เราต้องสร้างเครื่องสถานะด้วยตนเองและสลับการโทรกลับ

เราต้องการบางสิ่งบางอย่างระดับไฮเอนด์ที่มีการยศาสตร์ที่ดีขึ้น แต่ก็มีข้อดีอยู่ ความสามารถในการประกอบซึ่งสนับสนุนระบบนิเวศของนามธรรมแบบอะซิงโครนัสที่ทำงานร่วมกัน ฟังดูคุ้นเคยมาก: การดำเนินการบรรลุเป้าหมายเดียวกัน ฟิวเจอร์ส(หรือสัญญา) ในหลายภาษาที่รองรับน้ำตาลวากยสัมพันธ์ในรูปแบบ อะซิงก์/รอที่ด้านบน

ประเภทจำนวนเต็มดั้งเดิมที่โปรเซสเซอร์รองรับเป็นการประมาณที่จำกัดของชุดจำนวนเต็มอนันต์ที่เราใช้ในการจัดการในชีวิตจริง การแสดงแบบจำกัดนี้ไม่ตรงกับตัวเลข "จริง" เสมอไป เช่น 255_u8 + 1 == 0 บ่อยครั้งที่โปรแกรมเมอร์ลืมเกี่ยวกับความแตกต่างนี้ซึ่งอาจนำไปสู่ข้อบกพร่องได้ง่าย

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

เล็กน้อยเกี่ยวกับเหล็ก

Iron เป็นเฟรมเวิร์กเว็บระดับสูงที่เขียนด้วยภาษาการเขียนโปรแกรม Rust และสร้างขึ้นจากไลบรารีไฮเปอร์อีกไลบรารีที่มีชื่อเสียง Iron ได้รับการออกแบบมาเพื่อใช้ประโยชน์จากผลประโยชน์ทั้งหมดที่ Rust มอบให้เรา Iron พยายามหลีกเลี่ยงการปิดกั้นการดำเนินการในเคอร์เนล

ปรัชญา

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

  • ลักษณะ "ระดับกลาง" - ใช้เพื่อใช้ฟังก์ชันการทำงานแบบ end-to-end ในการประมวลผลคำขอ
  • ตัวแก้ไข - ใช้เพื่อแก้ไขคำขอและการตอบกลับในลักษณะที่เหมาะกับสรีระที่สุด

คุณจะคุ้นเคยกับส่วนพื้นฐานของตัวดัดแปลงและประเภทระดับกลางในระหว่างบทความ

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

ขั้นแรก เรามาสร้างโปรเจ็กต์โดยใช้ Cargo โดยใช้คำสั่ง:

โดยการรวบรวมเราจะได้สิ่งที่สอดคล้องกัน ไฟล์ปฏิบัติการ:

1 2 3 $rustc hello.rs $ du -h สวัสดี 632K สวัสดี

632 กิโลไบต์สำหรับการพิมพ์แบบธรรมดา?! Rust อยู่ในตำแหน่งที่เป็นภาษาของระบบที่มีศักยภาพในการแทนที่ C/C++ ใช่ไหม? แล้วทำไมไม่ลองทดสอบโปรแกรมที่คล้ายกันกับคู่แข่งที่ใกล้ที่สุดล่ะ?

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

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

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

ในการทดสอบที่ฉันจะแสดงด้านล่างนี้ Rust มีประสิทธิภาพเหนือกว่าการใช้งาน Java ของคิวที่ไม่มีการล็อคอย่างง่ายดาย และการใช้งาน Rust เองก็เขียนได้ง่าย

ฉันได้ใช้รูปแบบการเรียกคืนหน่วยความจำตามยุคสมัยในไลบรารี Crossbeam ใหม่ ซึ่งขณะนี้พร้อมที่จะใช้กับโครงสร้างข้อมูลของคุณแล้ว ในโพสต์นี้ ผมจะพูดถึงโครงสร้างข้อมูลที่ไม่มีการล็อค อัลกอริธึมยุค และ Rust API ภายใน

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

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

ฉันมีความคิดเล็กน้อยเกี่ยวกับการเรียนรู้ภาษาการเขียนโปรแกรม

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

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

สิ่งนี้คล้ายกับการพูดคุยเรื่องรถยนต์มาก คุณเคยได้ยินเกี่ยวกับ UAZ Rybak ใหม่หรือไม่? เขาเร็วแค่ไหน? ฉันสามารถขับรถข้ามทะเลสาบได้หรือไม่?

เมื่อเราพูดถึงภาษาในลักษณะเดียวกัน เราหมายความว่าภาษาเหล่านั้นใช้แทนกันได้ เช่นเดียวกับรถยนต์ ถ้าฉันรู้วิธีขับรถ Lada Saransk ฉันก็ขับ UAZ Rybak ได้โดยไม่มีปัญหา ความแตกต่างเพียงอย่างเดียวคือความเร็วและแผงหน้าปัดใช่ไหม?

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

หมายเหตุ: บทความนี้ถือว่าผู้อ่านคุ้นเคยกับ Rust FFI (การแปล), endianness และ ioctl

เมื่อสร้างการเชื่อมโยงสำหรับโค้ด C เราจะพบโครงสร้างที่มีสหภาพอย่างหลีกเลี่ยงไม่ได้ Rust ไม่มีการรองรับการรวมในตัว ดังนั้นเราจะต้องวางกลยุทธ์ด้วยตัวเอง ใน C สหภาพคือประเภทที่จัดเก็บ ประเภทต่างๆข้อมูลในพื้นที่หน่วยความจำเดียว มีเหตุผลหลายประการที่สนับสนุนการต่อข้อมูล เช่น การแปลงระหว่างการแทนเลขฐานสองของจำนวนเต็มและตัวเลขทศนิยม การใช้ pseudo-polymorphism และการเข้าถึงบิตโดยตรง ฉันจะมุ่งเน้นไปที่การหลอก-พหุสัณฐาน



2024 wisemotors.ru. วิธีนี้ทำงานอย่างไร. เหล็ก. การทำเหมืองแร่ สกุลเงินดิจิทัล