Go ปรับปรุงประสิทธิภาพการทำงานด้วยอินเทอร์เฟซ“ นัย” อย่างไรและเปรียบเทียบกับแนวคิดของ C # ของวิธีการขยายอย่างไร


21

ในการสอนภาษาไปพวกเขาอธิบายว่าอินเตอร์เฟสทำงานอย่างไร:

Go ไม่มีคลาส อย่างไรก็ตามคุณสามารถกำหนดวิธีการกับประเภทโครงสร้าง รับวิธีการที่ปรากฏในรายการอาร์กิวเมนต์ของตัวเองระหว่างคำหลัก func และชื่อวิธีการ

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

ประเภทอินเตอร์เฟสถูกกำหนดโดยชุดวิธีการ ค่าประเภทอินเตอร์เฟสสามารถเก็บค่าใดก็ได้ที่ใช้วิธีการเหล่านั้น

นี่เป็นวิธีเดียวในการสร้างส่วนต่อประสานใน Go Google อธิบายเพิ่มเติมว่า:

ชนิดที่ใช้อินเทอร์เฟซโดยใช้วิธีการ ไม่มีการประกาศเจตนาอย่างชัดเจน [ interfaceการประกาศเช่น]

อินเทอร์เฟซโดยนัย decouple ใช้งานแพคเกจจากแพคเกจที่กำหนดอินเทอร์เฟซ: ไม่ขึ้นอยู่กับอีก

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

ทั้งหมดนี้ฟังดูน่าสงสัยเช่นวิธีการขยายใน C #ยกเว้นวิธีการใน Go ที่เป็น polymorphic โหดเหี้ยม พวกเขาจะทำงานในประเภทใด ๆที่ใช้พวกเขา

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


ที่เกี่ยวข้อง: stackoverflow.com/q/11441905
Robert Harvey

1
อินเทอร์เฟซ Go เหล่านี้ฟังดูคล้ายกับแม่แบบ C ++ ที่สามารถทำได้มากกว่าวิธีการขยาย C # ใน C # ไม่มีอะไรเหมือน“ ประเภทใด ๆ ที่ใช้วิธีการ A และ B” แต่คุณสามารถทำได้โดยใช้เทมเพลต C ++
svick

ที่เกี่ยวข้อง: codeproject.com/Articles/9281/…
Robert Harvey

'อินเทอร์เฟซโดยนัย' ไม่ใช่แค่รูปแบบการพิมพ์เป็ดหรือไม่
Allon Guralnek

"อินเทอร์เฟซโดยนัย 'ไม่ใช่รูปแบบการพิมพ์เป็ดหรือไม่" อินเตอร์เฟสของ Go เป็นตัวอย่างของการพิมพ์เชิงโครงสร้าง แนวคิดที่คล้ายกันมาก
mortdeus

คำตอบ:


12

ฉันไม่เห็นวิธีการขยายและอินเทอร์เฟซโดยนัยเหมือนกันเลย

ก่อนอื่นเรามาพูดเพื่อวัตถุประสงค์

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

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

ตอนนี้ขอพูดถึงผลที่ตามมา

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

ผลกระทบของอินเทอร์เฟซโดยนัยเป็นบางสิ่ง

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

ประโยชน์ของวิธีการขยายในบุคลากร Linq ส่วนใหญ่จากความสามารถในการรับสินบนการดำเนินการวิธีการบนอินเตอร์เฟซ,โดยเฉพาะอย่างยิ่งและIEnumerable IQueryableในขณะที่คุณสามารถปลอมสิ่งนี้ด้วยstaticวิธีการในคลาสยูทิลิตี้มันจะเงอะงะ
Robert Harvey

@RobertHarvey ไม่จำเป็นต้องอ้างสิทธิ์ว่าวางวิธีไว้บนส่วนต่อท้ายโปรดสังเกตความแตกต่างระหว่างวิธีที่เกิดขึ้นจริงบนส่วนต่อประสานกับวิธีส่วนขยาย: วิธีในส่วนต่อประสานจะถูกนำมาใช้ภายในชั้นเรียนซึ่งใช้ส่วนต่อประสานนั้น มีการเข้าถึงอย่างมากมากกว่าวิธีการขยายใด ๆ อีกครั้งมันเป็นการเปลี่ยนแปลงในมุมมองรหัสที่ใช้ในชั้นเรียนจะได้รับมุมมองพิเศษเมื่อเทียบกับภายนอก
Jimmy Hoffa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.