ทำไมจึงมี "ใหม่" ใน Go


49

ฉันยังงงเหมือนว่าทำไมเราถึงnewไปกัน

เมื่อคุณต้องการสร้างอินสแตนซ์ของโครงสร้างให้ทำ

t := Thing{}

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

t := &Thing{}

แต่ยังมีความเป็นไปได้นี้:

t := new(Thing)

อันสุดท้ายดูเหมือนว่าคนต่างด้าวตัวเล็ก ๆ กับภาษาที่เหลือ &Thing{}มีความชัดเจนและรัดกุมเหมือนกันnew(Thing)และใช้โครงสร้างที่คุณมักใช้ที่อื่นเท่านั้น นอกจากนี้ยังขยายมากขึ้นในขณะที่คุณอาจจะเปลี่ยนไปหรือ&Thing{3} &Thing{Feets:7}

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

นอกจากนี้ยังทำให้คำที่สงวนไว้อีกหนึ่งคำ

ดังนั้นเหตุผลที่อยู่เบื้องหลังnewคืออะไร? บางครั้งมันมีประโยชน์หรือไม่ เราควรใช้มันหรือไม่?


1 : ใช่ฉันรู้ว่าไม่ใช่คำหลักในระดับไวยากรณ์คุณสามารถเงาได้แต่นั่นไม่ได้เปลี่ยนความจริงสำหรับนักพัฒนาที่เหมาะสมคำที่สงวนไว้


3
"... to Go coders ... " - นี่คือเหตุผล F # / Haskell / ฯลฯ เป็นนักพัฒนา C ที่แปลกมากและนั่นเป็นเหตุผลว่าทำไมพวกเขาถึงได้รับแรงฉุด ~ 0 สกาลาพยายามและตอนนี้มันเข้าถึงและได้ยินมากขึ้น
ชัด

12
ในความคิดเดียวกัน Python และ Ruby เป็นคนต่างด้าวมากสำหรับนักพัฒนา C เนื่องจากพวกเขาใช้คีย์เวิร์ดที่ไม่คุ้นเคยกฎการสร้างประโยคแปลก ๆ แต่พวกเขาไม่ได้รับแรงฉุด ~ 0 แต่ค่อนข้างตรงกันข้าม
Xion

8
@Xion: คุณดูอัตราการเติบโตเริ่มต้นของ Ruby หรือไม่ ต้องใช้เวลานานกว่าจะได้มาถึงจุดนี้ (18 ปีเพื่อความแม่นยำ) Python มีอายุมากกว่า (1991!)
Joachim Sauer

2
@AndresF ความต้านทานต่อสกาล่าบางอย่างอาจไม่เกี่ยวข้องกับภาษา ในฐานะโปรแกรมเมอร์อายุน้อย (อายุ 25 ปี) บางสิ่งเกี่ยวกับชื่อตัวเองทำให้ฉันนึกถึงภาษาที่มีพื้นฐานทางคณิตศาสตร์อย่าง Matlab (ซึ่งฉันมีความทรงจำไม่ดี) และภาษาที่เก่าแก่อย่าง Fortran ไม่เคยมีการกระตุ้นใด ๆ แม้แต่จะมองมัน
Izkata

4
หมายเหตุด้าน: ใหม่ไม่ใช่คำหลักใน Go มันเป็นฟังก์ชั่นในตัว
Manish Malik

คำตอบ:


44

วิธีที่ดีที่สุดที่จะถามคือคนที่ทำงาน สิ่งที่ฉันทำ !

tl; DR: แต่เดิมก่อนที่จะมีmakeและ&{}และก็ยังคงฟังก์ชั่นที่จะใช้ในบางสถานการณ์

โดยพื้นฐานแล้วนี่คือส่วนที่สำคัญที่สุดที่ยกมา:

ดังนั้นเหตุผลที่อยู่เบื้องหลังใหม่คืออะไร? มันมีประโยชน์ไหม? เราควรใช้มันหรือไม่?

คุณไม่สามารถทำได้หากไม่มีสิ่งใหม่

v := new(int)
*v++
fmt.Println(*v)

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

ไชโย

เดฟ

หลังจากคำตอบอื่นแสดงวิธีแก้ปัญหานี้:

vv := 0
v := &vv
*v++
fmt.Println(*v)

ฉันขอคำชี้แจงเพิ่มเติม:

โดยพื้นฐานแล้วประเด็นของเดฟไม่ได้อยู่อย่างนั้นเหรอ?

มีสถานที่ที่ไม่สะดวกที่จะแอบเข้าไปในตัวแปรใหม่เพื่อรับที่อยู่ของมัน

ใหม่ (T) มีความหมายตรงไปตรงมาทันทีแทนที่จะเป็นสำนวนแบบหลายขั้นตอน

จุดเดฟเท่านั้นถ้าตกอยู่เพียงความเป็นไปได้ทางเทคนิค (การทำโดยไม่ต้อง new) เป็นที่น่าสนใจในตัวเอง

สิ่งนี้ไม่ได้กล่าวถึงเพราะเห็นได้ชัดว่าควรจะมีเพราะเกือบทุกภาษามีหรือไม่

"เราจะเก็บไว้new" การสนทนาจะปรากฏขึ้นเป็นครั้งคราว เนื่องจากเราไม่สามารถนำมันออกได้จนกว่าจะไป 2 ถ้าฉันเข้าใจคำสัญญาอย่างถูกต้องดูเหมือนว่าจะไม่มากนักที่จะวนกลับวนซ้ำอีกครั้ง ตามเวลาที่ Go 2 คิดได้เราอาจมีแนวคิดที่แตกต่างและดีกว่า ...

คริส

นอกจากนี้ยังมีส่วนใหญ่ด้วยเหตุผลทางประวัติศาสตร์:

คุณต้องพิจารณาประวัติของโครงการ ฉันคิดว่ามีการเปิดตัวใหม่ก่อนที่จะมีการสร้าง

มันเป็นความจริง. อันที่จริงเราต้องดิ้นรนสักพักหนึ่งก่อนที่จะคิดทำ หากคุณดูบันทึกของที่เก็บคุณจะเห็นว่าการสร้างนั้นปรากฏขึ้นเฉพาะในเดือนมกราคม 2009 ให้แก้ไข 9a924177598f

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

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

เอียน


ฉันยินดีที่จะเห็นลิงก์ไปยังอีก"เราจะให้ใหม่หรือไม่" การอภิปรายซึ่งปรากฏขึ้นเมื่อเวลาผ่านไป
Denys Séguret

มีบางอย่างในการป้องกันไม่ให้คุณทำv := &(0)และข้ามตัวแปร temp หรือไม่ (ฉันไม่ไปเลย)
Alex Feinman

3
@AlexFeinman ในฐานะที่0เป็นค่าคงที่ตัวอักษรคุณไม่สามารถใช้ที่อยู่ของมัน ปัญหาจะเกิดขึ้นหากคุณต้องการประเภทที่เฉพาะเจาะจงเช่นกัน นั่นเป็นเหตุผลที่ไวยากรณ์เหมือน&intหรือ&int(0)อาจมีประโยชน์ (ไม่ได้คิดมากเกี่ยวกับไวยากรณ์ที่ดีที่สุด) แต่การทำมันในสองบรรทัดเป็นคอลลินส์ก็แสดงว่าดีเช่นกัน ( vv := 0; v := &vv)
Denys Séguret

14
"เนื่องจากเราไม่สามารถนำมันออกได้จนกว่าจะไป 2" ซึ่งตามที่ทุกคนรู้ว่าจะไม่เกิดขึ้นเพราะGo 2ถือว่าเป็นอันตราย
Mason Wheeler

2
@MasonWheeler คุณเกือบจะฆ่าฉัน ... ยังคงหัวเราะที่ "Go 2 ถือว่าเป็นอันตราย" ... แปลกมากพอที่ฉันกำลังพูดถึงบทความวันนี้ที่อาหารกลางวัน
Daniela Petruzalek
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.