golang "ไม่ได้กำหนด" ฟังก์ชันที่ประกาศในไฟล์อื่นหรือไม่


136

ฉันกำลังพยายามเขียนโปรแกรม go พื้นฐานที่เรียกใช้ฟังก์ชันในไฟล์อื่น แต่เป็นส่วนหนึ่งของแพ็คเกจเดียวกัน อย่างไรก็ตามผลตอบแทน:

undefined: NewEmployee

นี่คือซอร์สโค้ด:

main.go:

package main

func main() {
emp := NewEmployee()    
}

employee.go:

package main

type Employee struct {
    name string
    age int
}   

func NewEmployee() *Employee {
    p := &Employee{}
    return p
}

func PrintEmployee (p *Employee)  {
    return "Hello world!"
}

ไฟล์ของคุณมีคำสั่งแพ็คเกจหรือไม่ สิ่งที่คุณพิมพ์ไม่มี a package xนอกจากนี้แพ็คเกจหลักของคุณมักจะมีเพียงไฟล์เดียวจากนั้นจึงนำเข้าชิ้นส่วนอื่น ๆ ที่ต้องการ
Chris Pfohl

8
คุณกำลังใช้go run? (และดูgolang.org/doc/code.html )
JimB

1
@JuanM คำถามของฉันคือที่มาที่สมบูรณ์ของmain.goและemployee.go? เนื่องจากไฟล์ go ทั้งหมดควรมีคำสั่งแพ็กเกจและฉันไม่เห็นอะไรเลยในไฟล์ของคุณ ดู: golang.org/doc/code.html#PackageNames
Chris Pfohl

1
func สุดท้ายของ staff.go ไม่ถูกต้อง (ไม่มีชื่อฟังก์ชันไม่มีการประกาศประเภทผลตอบแทน) ไม่ใช่ปัญหาที่คุณถาม แต่แสดงให้เห็นว่ามีปัญหามากขึ้น คุณสามารถโพสต์รหัสที่สมบูรณ์และข้อผิดพลาดทั้งหมดในขณะรวบรวม
siritinga

1
แล้วแสดงให้เราเห็นว่าคุณกำลังทำอะไรอยู่! GOPATH รหัสจริงและวิธีที่คุณเรียกใช้goเครื่องมือ
JimB

คำตอบ:


173

โปรดอ่าน"วิธีการเขียนโค้ดไป"

อย่าใช้/srcในGOPATHไฟล์. แพ็คเกจอยู่ใน$GOPATH/src.

สำหรับbuildหรือinstallคุณต้องมีไฟล์ของคุณในไดเร็กทอรีแพ็กเกจ

สำหรับgo runคุณต้องจัดหาไฟล์ทั้งหมดเป็นอาร์กิวเมนต์:

go run main.go employee.go

แต่คุณควรใช้เกือบตลอดเวลาgo installหรือgo build(และโดยเฉพาะอย่างยิ่งในอดีตเนื่องจากgo buildทำให้เกิดความสับสนเมื่อทำงานกับแพ็คเกจที่ไม่ใช่แพ็คเกจหลัก)


ขอบคุณสำหรับข้อมูลที่ @JimB! ฉันแก้ไขตัวแปรสภาพแวดล้อม (ฉันลืมที่จะตั้งค่า GOBIN ด้วย) ย้ายไฟล์ของฉันไปยังตำแหน่งที่ถูกต้อง แต่เมื่อฉันลองติดตั้งฉันได้รับข้อผิดพลาดเดียวกัน ข้อเสนอแนะใด ๆ ?
Juan M

คุณแน่ใจหรือไม่ว่าไม่มีข้อผิดพลาดอื่น ๆ ไฟล์ Employ.go ของคุณไม่สามารถรวบรวมได้ตามที่เป็นอยู่ ไม่งั้นฉันต้องดูว่าคุณกำลังทำอะไรอยู่ เส้นทางที่แน่นอนการเรียกร้อง ฯลฯ
JimB

8
หรือทำ $ go run * .go
Puran

การรัน$ go run *.goจะเป็นทางลัดแทนที่จะเรียกใช้ไฟล์ทั้งหมด
offerni

61

ฉันเพิ่งมีปัญหาเดียวกันใน GoLand (ซึ่งก็คือ Intellij IDEA for Go) และหาวิธีแก้ปัญหา คุณจำเป็นต้องเปลี่ยนRun kindจากFileการหรือPackage Directoryคุณสามารถเลือกได้จากเมนูแบบเลื่อนลงหากคุณเข้าไปที่Run/EditConfigurations

เช่น: สำหรับแพ็คเกจ~/go/src/a_packageให้ใช้ a Package pathof a_packageand a Directoryof ~/go/src/a_packageand Run kindof Packageor Directory.


1
ขอบคุณนี่คือสิ่งที่ฉันกำลังมองหา โปรดระบุว่าคำตอบของคุณเกี่ยวกับ Intellij IDEA
kivagant

13

หากคุณกำลังใช้ทำgo run go run *.goโดยอัตโนมัติจะค้นหาไฟล์ go ทั้งหมดในไดเร็กทอรีการทำงานปัจจุบันคอมไพล์แล้วเรียกใช้ฟังก์ชันหลักของคุณ


มีความล้มเหลวในการทำเช่นนี้หรือไม่? นี่เป็นคำตอบที่ง่ายที่สุดสำหรับคำถาม OP
Stavros_S


8

คุณสามารถลองทำอย่างใดอย่างหนึ่งต่อไปนี้:

วิธีที่ 1 :

  • สมมติว่าชื่อโครงการของคุณคือ MyProject
  • ไปที่เส้นทางของคุณวิ่ง go build
  • มันจะสร้างไฟล์ปฏิบัติการเป็นชื่อโปรเจ็กต์ของคุณ ("MyProject")
  • จากนั้นเรียกใช้ไฟล์ปฏิบัติการโดยใช้ ./MyProject

go build && ./MyProjectคุณสามารถทำทั้งสองขั้นตอนในครั้งเดียวโดยพิมพ์ ไปที่ไฟล์package mainถูกคอมไพล์เป็นไฟล์ปฏิบัติการ

วิธีที่ 2 :

  • go run *.goวิ่งเพียง จะไม่สร้างไฟล์ปฏิบัติการใด ๆ แต่รัน

3

หากคุณต้องการเรียกใช้ฟังก์ชันจากไฟล์ go อื่นและคุณกำลังใช้ Goland ให้ค้นหาตัวเลือก "แก้ไขการกำหนดค่า" จากเมนู Run และเปลี่ยนประเภทการเรียกใช้จากไฟล์เป็นไดเรกทอรี มันจะล้างข้อผิดพลาดทั้งหมดและช่วยให้คุณสามารถเรียกใช้ฟังก์ชันจากไฟล์ go อื่น ๆ


1

ฉันพบปัญหาเดียวกันกับGo11เพียงแค่ต้องการแบ่งปันวิธีที่ฉันแก้ปัญหานี้เพื่อช่วยเหลือผู้อื่นในกรณีที่พวกเขาพบปัญหาเดียวกัน

ฉันมีโครงการ Go ของฉันอยู่ข้างนอก $GOPATHดังนั้นฉันจึงต้องเปิดGO111MODULE=onโดยไม่เปิดตัวเลือกนี้มันจะทำให้คุณมีปัญหานี้ แม้ว่าคุณจะพยายามสร้างหรือทดสอบทั้งหมดpackageหรือdirectoryจะไม่สามารถแก้ไขได้หากไม่มีGO111MODULE=on


1

go run .จะเรียกใช้ไฟล์ทั้งหมดของคุณ จุดเริ่มต้นคือฟังก์ชันmain()ที่จะต้องไม่ซ้ำกันกับmainแพ็กเกจ

อีกทางเลือกหนึ่งคือการสร้างไบนารีด้วยgo buildและเรียกใช้


ฉันใช้งานโปรเจ็กต์ go เก่ามาพักหนึ่งแล้วและลืมวิธีการวิ่ง ในที่สุดฉันก็พบกับคำตอบของคุณ นี่ควรเป็นคำตอบที่ได้รับการโหวต!
moondaddi

1

คุณควรใช้โมดูล goตอนนี้หากคุณไม่ได้ติดตามHow to write go code

ด้วยโมดูล go คุณไม่จำเป็นต้องใส่รหัสใน $ GOPATH / src มันสามารถอาศัยอยู่ในสถานที่อื่นได้เช่นกัน

คุณสามารถย้ายรหัสไปยังไดเร็กทอรีอื่นเช่น / พนักงานเพื่อให้ทำงานได้ภายใต้ไดเร็กทอรีพนักงานเริ่มต้นโมดูล go

go mod init example.com/employee

0

เพียงใช้คำสั่งgo run *.goเพื่อเรียกใช้ไฟล์ go ทั้งหมดในแพ็คเกจของคุณ!


คำตอบก็เหมือนคำตอบของ
@Paul

-1

ถ้าโฟลเดอร์ต้นทางของคุณมีโครงสร้าง / go / src / บล็อก (สมมติว่าชื่อโฟลเดอร์ต้นทางของคุณคือบล็อก)

  1. cd / go / src / blog ... (cd อยู่ในโฟลเดอร์ที่มีแพ็คเกจของคุณ)
  2. ไปติดตั้ง
  3. บล็อก

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


คุณตระหนักgo installและgo buildแตกต่างกันหรือไม่? และปฏิบัติการถูกเรียกใช้และไม่ได้./<executable> blogตามที่คุณได้ใช้go installมันในของคุณGOPATH/bin(แม้จะต่อท้าย $ PATH ของคุณด้วย) และนั่นเป็นเหตุผลที่blogเหมาะกับคุณ
shmsr

ฉันอาจไม่ได้บอกคุณเกี่ยวกับวิศวกรรมซอฟต์แวร์ แต่ฉันจะบอกคุณเกี่ยวกับวิธีการพูดคุยกับผู้คน? การพยายามพูดอย่างเอื้อเฟื้อเหมือนคุณไม่ใช่เรื่องดีที่ควรทำ คุณสามารถพูดได้ว่า "มีความแตกต่างระหว่างgo installและgo build" อย่างไรก็ตามใช่ฉันรู้ว่ามันต่างกัน หากฉันแนะนำให้ทำgo buildแทนgo installฉันจะบอกด้วยว่าคุณต้องเรียกใช้./executableไฟล์. . วิธีที่ฉันแนะนำก็ใช้ได้กับคุณเช่นกัน ลองใช้งานในขณะที่คุณอยู่ที่นั่น ไชโย!
Druhin Bala

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