ฉันค่อนข้างคุ้นเคยกับ Go โดยเขียนโปรแกรมขนาดเล็กจำนวนมากในนั้น แน่นอนว่าสนิมฉันไม่คุ้นเคย แต่จับตาดู
เมื่อเร็ว ๆ นี้อ่านhttp://yager.io/programming/go.htmlฉันคิดว่าฉันควรตรวจสอบสองวิธีที่ Generics ได้รับการจัดการเพราะบทความดูเหมือนจะวิพากษ์วิจารณ์อย่างไม่เป็นธรรมไปเมื่อในทางปฏิบัติมีอะไรมากที่อินเตอร์เฟส ไม่สามารถทำได้อย่างสวยงาม ฉันยังคงได้ยินโฆษณาต่อไปเกี่ยวกับลักษณะของ Rust ที่ทรงพลังและไม่มีอะไรนอกจากการวิจารณ์จากคนเกี่ยวกับ Go มีประสบการณ์ใน Go ฉันสงสัยว่าความจริงมันเป็นอย่างไรและอะไรคือความแตกต่างในท้ายที่สุด สิ่งที่ฉันพบคือลักษณะและการเชื่อมต่อมีความคล้ายคลึงกัน! ท้ายที่สุดฉันไม่แน่ใจว่าฉันขาดอะไรบางอย่างดังนั้นนี่คือบทสรุปการศึกษาที่รวดเร็วเกี่ยวกับความคล้ายคลึงกันของพวกเขาเพื่อให้คุณสามารถบอกฉันว่าฉันพลาดอะไรไป!
ตอนนี้ขอใช้เวลาดูไปเชื่อมต่อจากพวกเขาเอกสาร :
อินเทอร์เฟซในตัวไปมีวิธีในการระบุพฤติกรรมของวัตถุ: หากมีสิ่งใดสามารถทำได้ก็สามารถใช้ที่นี่ได้
ส่วนใหญ่แล้วอินเตอร์เฟสจะStringer
ส่งคืนสตริงที่แสดงถึงวัตถุ
type Stringer interface {
String() string
}
ดังนั้นวัตถุใด ๆ ที่มีการString()
กำหนดไว้เป็นStringer
วัตถุ นี้สามารถใช้ในลายเซ็นประเภทเช่นที่func (s Stringer) print()
ใช้วัตถุเกือบทั้งหมดและพิมพ์
นอกจากนี้เรายังมีinterface{}
สิ่งที่ใช้วัตถุใด ๆ จากนั้นเราจะต้องกำหนดประเภทของรันไทม์ผ่านการสะท้อนกลับ
ตอนนี้เรามาดูลักษณะของสนิมจากเอกสารประกอบ :
ที่ง่ายที่สุดลักษณะคือชุดของลายเซ็นวิธีการศูนย์หรือมากกว่า ตัวอย่างเช่นเราสามารถประกาศลักษณะที่พิมพ์ได้สำหรับสิ่งที่สามารถพิมพ์ไปยังคอนโซลด้วยลายเซ็นวิธีการเดียว:
trait Printable {
fn print(&self);
}
สิ่งนี้ดูคล้ายกับอินเทอร์เฟซของเราในทันที ความแตกต่างเดียวที่ฉันเห็นคือเรากำหนด 'การนำไปใช้' ของลักษณะแทนที่จะเป็นเพียงการกำหนดวิธีการ ดังนั้นเราทำ
impl Printable for int {
fn print(&self) { println!("{}", *self) }
}
แทน
fn print(a: int) { ... }
คำถามโบนัส:จะเกิดอะไรขึ้นในสนิมหากคุณกำหนดฟังก์ชั่นที่ใช้คุณสมบัติ แต่ไม่ได้ใช้impl
? มันไม่ทำงานเหรอ?
ซึ่งแตกต่างจาก Go's Interfaces ระบบชนิดของ Rust มีพารามิเตอร์ชนิดที่ให้คุณทำ generics และสิ่งที่เหมาะสมเช่นinterface{}
ในขณะที่คอมไพเลอร์และรันไทม์รู้ประเภท ตัวอย่างเช่น,
trait Seq<T> {
fn length(&self) -> uint;
}
ทำงานกับประเภทใดก็ได้และคอมไพเลอร์รู้ว่าประเภทขององค์ประกอบลำดับที่เวลารวบรวมมากกว่าการใช้การสะท้อน
ตอนนี้คำถามจริง: ฉันไม่มีความแตกต่างที่นี่หรือไม่? พวกเขาเป็นจริงที่คล้ายกัน? ไม่มีความแตกต่างพื้นฐานที่ฉันขาดหายไปที่นี่ใช่หรือไม่ (ในการใช้งานรายละเอียดการใช้งานมีความน่าสนใจ แต่ท้ายที่สุดก็ไม่สำคัญว่าจะทำงานเหมือนกันหรือไม่)
นอกจากความแตกต่างทางไวยากรณ์ความแตกต่างที่แท้จริงที่ฉันเห็นคือ:
- Go มีวิธีการจัดส่งแบบอัตโนมัติกับ Rust ต้องการ (?)
impl
เพื่อสร้างคุณลักษณะ- สง่างามและชัดเจน
- สนิมมีพารามิเตอร์ประเภทที่อนุญาตให้ใช้ยาชื่อสามัญที่เหมาะสมโดยไม่มีการสะท้อนกลับ
- ไปจริงๆไม่มีการตอบสนองที่นี่ นี่เป็นสิ่งเดียวที่มีประสิทธิภาพมากขึ้นอย่างมากและในที่สุดก็เป็นเพียงวิธีการคัดลอกและวางที่มีลายเซ็นประเภทที่แตกต่างกัน
สิ่งเหล่านี้เป็นความแตกต่างที่ไม่สำคัญหรือไม่? ถ้าเป็นเช่นนั้นก็จะปรากฏว่าระบบอินเตอร์เฟส / ประเภทของโกในทางปฏิบัติไม่อ่อนแอเท่าที่รับรู้
AnyMap
map[string]interface{}