วิธีปิดใช้งานข้อผิดพลาดการนำเข้าที่ไม่ได้ใช้ Golang


101

โดยค่าเริ่มต้น Go ถือว่าการนำเข้าที่ไม่ได้ใช้เป็นข้อผิดพลาดบังคับให้คุณลบการนำเข้า ฉันต้องการทราบว่ามีความหวังที่จะเปลี่ยนพฤติกรรมนี้หรือไม่เช่นลดการเตือน

ฉันพบว่าปัญหานี้น่ารำคาญมากทำให้ฉันไม่สนุกกับการเขียนโค้ดใน Go

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

ฉันกำลังทำขั้นตอนนี้ซ้ำแล้วซ้ำเล่าเมื่อพัฒนาโปรแกรม GAE


1
ไม่ควรทิ้งการนำเข้าที่ไม่ได้ใช้ไว้ในโค้ดของคุณ แต่คุณสามารถแสดงความคิดเห็นได้ชั่วคราว
elithrar

76
ฉันยอมรับว่าไม่ใช่ความคิดที่ดีที่จะทิ้งการนำเข้าที่ไม่ได้ใช้ แต่เป็นความคิดที่ดีที่จะเสียความพยายามของโปรแกรมเมอร์ไปโดยไม่จำเป็นโดยเฉพาะอย่างยิ่งสิ่งนี้เกิดขึ้นบ่อยมากเมื่อทำการทดสอบบางสิ่ง การโหวตลงคะแนนจะต้องเป็นไปเพื่อทัศนคติของฉันที่มีต่อ GO โดยแฟน ๆ Go
Nick

6
มันเป็นคุณสมบัติไม่ได้เป็นปัญหา
beatgammit

1
การลบการนำเข้าที่ไม่ได้ใช้ออกไปเป็นสิ่งที่ดี มีคำแนะนำรูปแบบมากมายที่ต้องการให้คำเตือนทั้งหมดถือเป็นข้อผิดพลาดดังนั้นการเพิ่มคำเตือนใหม่จึงเป็นความคิดที่ไม่ดี บางทีแฟล็ก -dev อาจเป็นการประนีประนอมที่เป็นไปได้ แต่ก็var _ = <module>.Functionใช้ได้ดีและเห็นได้ชัดพอที่จะป้องกันไม่ให้เป็นเรื่องธรรมดา
deft_code

1
ในขณะที่มีคนตอบในคำตอบด้านล่างฉันขอแนะนำให้ใช้ IDE ที่จัดการการนำเข้า (Gogland, LiteIDE ฯลฯ - มีหลายตัว) หรือgoimportsเป็นขั้นตอนในกระบวนการสร้างของคุณ ถ้าไม่มีอย่างใดอย่างหนึ่งมันจะเก่าเร็วจริงๆ
Josef Grahn

คำตอบ:


40

การเพิ่มขีดล่าง ( _) ก่อนชื่อแพ็กเกจจะละเว้นข้อผิดพลาดในการนำเข้าที่ไม่ได้ใช้

นี่คือตัวอย่างวิธีการใช้งาน:

import (
    "log"
    "database/sql"

    _ "github.com/go-sql-driver/mysql"
)

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

ดูเพิ่มเติมที่https://golang.org/ref/spec#Import_declarations


นี่คือคำตอบที่ถูกต้อง ตามข้อมูลจำเพาะของ GoLang Doc มีวัตถุประสงค์เพื่อใช้ในการนำเข้าแพ็คเกจสำหรับผลข้างเคียงเท่านั้น (การเริ่มต้น) GoLang Spec Doc ที่นี่: golang.org/ref/spec#Import_declarations
จะ

ยอดเยี่ยมเพียง สิ่งนี้ควรอยู่ในรายชื่อสิบอันดับแรกที่นักพัฒนาซอฟต์แวร์มือใหม่ควรรู้ในโกลัง ขอขอบคุณ!
JM Janzen

13
ไม่ค่อยมีประโยชน์. ปัญหานี้คือหากคุณต้องการใช้การนำเข้าอีกครั้งในภายหลังคุณต้องลบออก_(มิฉะนั้นจะไม่สามารถอ้างอิงแพ็คเกจได้เนื่องจากไม่มีชื่อ) หากคุณกำลังจะทำเช่นนั้นคุณอาจแสดงความคิดเห็น / ไม่แสดงความคิดเห็น var _ = ...เคล็ดลับไม่ได้มีปัญหานี้
EM0

หากคุณเพิ่มขีดล่าง"fmt"ใน Gogland มันจะเพิ่มโดยอัตโนมัติ"fmt"เพื่อให้คุณมีทั้งสอง_"fmt"และ"fmt"ซึ่งทำให้มันไร้ประโยชน์ใน IDE นี้
kramer65

26

var _ = fmt.Printfเคล็ดลับที่เป็นประโยชน์ที่นี่


ฉันชอบวิธีนี้ มันน่าเกลียดพอที่จะทำให้มันไม่เป็นที่ต้องการ แต่มันก็ใช้ได้ถ้าคุณต้องการจริงๆ
deft_code

3
ดูรายละเอียดเพิ่มเติมได้ที่ลิงค์tip.golang.org/doc/effective_go.html#blank_unused
Deepak Singh Rawat

3
มันมีประโยชน์ในตอนนี้ แต่เมื่อฉันใช้เทคนิคนี้ฉันมักจะไม่ย้อนกลับไปและลบตัวระบุว่างที่ไม่ได้ใช้ในภายหลังทำให้การนำเข้าค้างเมื่อฉันไม่ได้ตั้งใจจะใช้มันในระยะยาว การใช้เครื่องมือเช่น goimports ช่วยแก้ปัญหาที่แท้จริงและทำให้มั่นใจได้ว่าการนำเข้าของฉันจะน้อยที่สุดและสะอาดอยู่เสมอ
mdwhatcott

ยังคงเป็นแฮ็คโง่ในความคิดของฉันแม้ว่าอาจเป็นสิ่งที่มีประสิทธิภาพที่สุดที่ต้องทำ
Anthony

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

22

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

หากคุณกำลังสนใจคุณสามารถดูนี้ที่https://github.com/dtnewman/modified_golang_compiler

ตอนนี้ฉันสามารถเรียกใช้โค้ดด้วยคำสั่งเช่นgo run -gcflags '-unused_pkgs' test.goและจะไม่ทำให้เกิดข้อผิดพลาด "unused import" เหล่านี้ ถ้าฉันไม่ใช้แฟล็กเหล่านี้มันจะกลับสู่ค่าเริ่มต้นที่จะไม่อนุญาตให้นำเข้าที่ไม่ได้ใช้

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


2
ฉันได้ทำเช่นเดียวกันกับรุ่น 1.6 ตรวจสอบที่นี่หากสนใจ: github.com/ronelliott/go/tree/release-branch.go1.6หมายเหตุ: การทดสอบบางอย่างจะล้มเหลว
Ron E

2
ฉันชอบความคิดเบื้องหลังนี้ ฉันเห็นว่าคุณส้อมยังอยู่ที่เวอร์ชัน 1.2 ซึ่งทำให้ไม่มีประโยชน์ สิ่งนี้ควรรวมอยู่ในคอมไพเลอร์ go มาตรฐานอย่างน้อยที่สุดเพื่อgo run main.goปิดใช้งานข้อผิดพลาดตามค่าเริ่มต้นในขณะที่go buildเปิดใช้งานข้อผิดพลาด วิธีนี้ง่ายต่อการพัฒนาโดยใช้go runและเมื่อถึงเวลาสร้างสำหรับการผลิตคุณยังคงถูกบังคับให้ล้างโค้ดของคุณ
kramer65

18

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


นี่คือคำตอบที่ถูกต้องอย่างเป็นกลาง 1. ใช้ go imports 2. กำหนดค่าตัวแก้ไขของคุณให้จัดรูปแบบในบันทึก 3. ทำฝันร้ายนี้ให้สำเร็จ
Simon Merrick

5

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


5
หรือฟังก์ชัน builtin printlnที่ผู้คนมักจะลืมนึกถึง
MatrixFrog

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

1
บิวอินprintln?? นี่เป็นข่าวกับฉัน มันไม่มีเอกสาร? หาที่ไหนไม่ได้แล้ว
แมตต์

1
@nemo จุดดี. เหมาะอย่างยิ่งสำหรับเมื่อคุณต้องการพิมพ์บางอย่างออกมาเป็นครั้งเดียวอย่างรวดเร็ว แต่คุณไม่ได้ตั้งใจจะเช็คอินจริง ๆ อาจไม่ดีที่จะใช้ในกรณีอื่น ๆ
MatrixFrog

1
@MartinTournoij - ฉันไม่เห็นด้วย นี่เป็นวิธีแก้ปัญหาที่ฉันพบในที่สุดเมื่อฉันมีปัญหานี้เมื่อ 5 ปีก่อนและด้วยการโหวตมากกว่า 5 ครั้งมันช่วยคนอื่นได้อย่างชัดเจน ฉันเป็นมือใหม่ที่ใช้fmtแพ็คเกจสำหรับการบันทึกโดยไม่รู้ว่ามีแพ็คเกจการบันทึกสำเร็จรูป
OldCurmudgeon

5

ใช้if false { ... }เพื่อแสดงความคิดเห็นเกี่ยวกับโค้ด รหัสภายในวงเล็บปีกกาต้องถูกต้องตามหลักไวยากรณ์ แต่อาจเป็นรหัสไร้สาระได้


3
ต้องมีตัวแปรอ้างอิงใด ๆ (เช่น foo.Bar) มากกว่าที่ถูกต้องตามหลักไวยากรณ์เป็นต้น
Dragon

นี่ไม่สะอาดหรือเป็นสำนวน มีเหตุผลว่าทำไม Go จึงได้รับการออกแบบในแบบที่เป็น
Acidic 9

1
นี่เป็นเทคนิคที่ดีเมื่อเราลองทำสิ่งต่างๆในขณะที่พัฒนาสคริปต์หรือสำรวจ API ใน Golang ขอบคุณ topskip!
Jay Taylor

2

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

เพื่อให้สั้นการนำเข้าที่ไม่ได้ใช้ถือเป็นข้อผิดพลาดใน Go เนื่องจากทำให้โปรแกรมเสียหายและทำให้การคอมไพล์ช้าลง การใช้การนำเข้าสำหรับผลข้างเคียง (_) เป็นวิธีแก้ปัญหาอย่างไรก็ตามฉันพบว่าสิ่งนี้สับสนในบางครั้งเมื่อมีการนำเข้าที่ถูกต้องผสมกับผลข้างเคียงพร้อมกับผลข้างเคียงที่นำเข้ามาเพื่อจุดประสงค์ในการดีบัก / ทดสอบโดยเฉพาะอย่างยิ่งเมื่อฐานรหัสเป็น มีขนาดใหญ่และมีโอกาสที่จะลืมและไม่ลบโดยไม่ได้ตั้งใจซึ่งอาจทำให้วิศวกร / ผู้ตรวจสอบรายอื่นสับสนในภายหลัง ฉันเคยแสดงความคิดเห็นเกี่ยวกับสิ่งที่ไม่ได้ใช้อย่างไรก็ตาม IDE ยอดนิยมเช่นรหัส VS และ Goland สามารถใช้งานgoimportsได้อย่างง่ายดายซึ่งจะทำการแทรกและลบการนำเข้าได้ค่อนข้างดี โปรดดูลิงค์สำหรับข้อมูลเพิ่มเติมhttps://golang.org/doc/effective_go.html#blank_import


ขอบคุณสำหรับสิ่งนี้! ฉันขอแนะนำให้คัดลอกบรรทัดของโค้ดจาก URL ที่คุณโพสต์ไว้ในคำตอบอย่างชัดเจนเพื่อเป็นตัวอย่างที่ชัดเจนในการนำเข้าสำหรับผลข้างเคียง: import _ "net/http/pprof"
Dragon

1
ขอบคุณ @Dragon สำหรับคำแนะนำของคุณ! เนื่องจากฉันเป็นผู้ให้ข้อมูลใหม่ด้วยความช่วยเหลือจากผู้คนเช่นคุณฉันจะพัฒนาโพสต์ของฉันได้ดีขึ้นอย่างรวดเร็ว
sbcharr

-1

วางสิ่งนี้ไว้ด้านบนของเอกสารของคุณและลืมเกี่ยวกับการนำเข้าที่ไม่ได้ใช้:

import (
    "bufio"
    "fmt"
    "os"
    "path/filepath"
)

var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs

1
แทนที่จะทำให้คอมไพเลอร์สร้างรหัสตายถ้าคุณอยากจะทำเช่นนี้ใช้_ตัวแปรทั่วโลกแทน (เช่นคนใดคนหนึ่งแพคเกจต่อบรรทัดหรือถ้าคุณยืนยันร่วมกันทั้งหมดเช่น: var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs) goimportsแต่ไม่ได้ทำเช่นนี้เพียงแค่ใช้
Dave C
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.