เมื่อใดควรใช้ def ใน Groovy


23

ฉันได้รับการพัฒนาใน Groovy สักครู่แล้วและฉันสงสัยว่าฉันควรจะใช้การคัดเลือกนักแสดงแบบไดนามิกบ่อยแค่ไหนdef? เพื่อนร่วมงานของฉันเชื่อว่าเราควรใช้มันเสมอเพราะช่วย Groovy ในวิธีที่ฉันไม่เข้าใจ

ขณะนี้เมื่อประกาศเมธอดส่งคืนชนิดและอาร์กิวเมนต์ฉันชอบที่จะจงใจระบุว่าควรนำวัตถุใดบ้างและคายออกมา (สำหรับการอ่านรหัสและฉันมาจากพื้นหลัง Java มันสมเหตุสมผลกับฉัน):

String doSomething(String something){
    //code
}
// vs
def doSomething(def somthing){
    //code
}
// vs 
def doSomething(somthing){
    // code
}

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


3
ดูที่นี่สิ่งที่เพื่อนร่วมงานของคุณเชื่อใน: stackoverflow.com/questions/184002/… .
Remigijus Pankevičius

ฉันเห็นคำถามนั้นและคำตอบจริง ๆ ก่อนตัดสินใจถามคำถามนี้ "แนวปฏิบัติที่ดีในสคริปต์ที่ใหญ่กว่าคือใช้คีย์เวิร์ด" def "เสมอดังนั้นคุณจะไม่พบปัญหาการกำหนดขอบเขตแปลก ๆ หรือรบกวนตัวแปรที่คุณไม่ต้องการ" -Ted Naleid ฟังดูดีสำหรับฉันเมื่อตัดสินใจระหว่างการละเว้นประเภทใด ๆ หรือการใช้ def ในสคริปต์ แต่สิ่งที่เกี่ยวกับการประกาศเมธอดส่งคืนชนิดและชนิดอาร์กิวเมนต์ การปฏิบัติที่ดีคืออะไร?
PJT

1
ตกลงฉันเห็นจุดของคุณแล้ว มันเป็นคำถามเกี่ยวกับการเขียนโปรแกรมแบบไดนามิกและแบบไดนามิก ประเภทของการอภิปรายฉันพยายามหลีกเลี่ยงเนื่องจากสงครามไฟข้างหน้า :)
Remigijus Pankevičius

คำตอบ:


20

ในฐานะที่เป็นแนวปฏิบัติที่ดีในการเขียนโปรแกรม (แม้กระทั่งการเขียนสคริปต์) ให้พิจารณาการระบุชนิดที่แน่นอน (แต่ไม่จำเป็นต้องเป็นรูปธรรม) สำหรับตัวแปร ใช้defเฉพาะในกรณีที่ไม่มีประเภทที่แน่นอนที่ใช้กับตัวแปร

เนื่องจาก OP รู้จัก Java จึงไม่ต่างจากการระบุประเภทของObject(แม้ว่าจะมีความแตกต่างเล็กน้อย ) คำตอบสำหรับคำถามนี้จะไม่แตกต่างจากการตอบคำถามเช่น: "ทำไมไม่ใช้Objectประเภทใน Java เสมอไป"

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

เช่นวิธีการนี้เหมาะสมกับอาร์กิวเมนต์ชนิดที่แน่นอนและชนิดส่งคืน:

// def val or Object val, opens up the possibility
// of the caller sending a non-numeric value 
Number half(Number val) {  
    val/2
}

ในขณะที่วิธีนี้เหมาะสมกับประเภท def

// I'd let them pass an argument of any type; 
// type `Object` makes sense too
def getIdProperty(def val) {   
    if(val?.hasProperty('id')) {
        // I don't know the type of this returned 
        // value and I don't really need to care 
        return val.id            
    }
    else {
        throw new IllegalArgumentException("Argument doesn't have an 'id' property")
    }
}

-1

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.