golang «неопределенная» функция объявлена ​​в другом файле?


135

Я пытаюсь написать базовую программу 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!"
}

у ваших файлов есть инструкции пакета? У того, что вы набрали, нет package x, также ваш основной пакет обычно содержит только один файл, а затем импортирует другие части, которые ему нужны,
Крис Пфол,

8
ты используешь go run? (и см. golang.org/doc/code.html )
JimB

1
@JuanM, мой вопрос был в том, что это полный источник main.goи employee.go? Потому что все файлы go должны иметь оператор пакета, а я его не вижу в вашем. См .: golang.org/doc/code.html#PackageNames
Крис Пфол,

1
Последняя функция employee.go неверна (нет имени функции, не объявлен тип возврата). Это не та проблема, о которой вы просите, но это показывает, что проблем больше. Не могли бы вы опубликовать полный код и полную ошибку при компиляции?
siritinga

1
тогда покажи нам, что ты делаешь! GOPATH, фактический код и то, как вы вызываете goинструмент.
JimB

Ответы:


173

Прочтите, пожалуйста, «Как написать код Go» .

Не используйте /srcв своем GOPATH. Пакеты расположены в $GOPATH/src.

Для buildили installвам нужно, чтобы ваши файлы были в каталоге пакета.

В go runкачестве аргумента необходимо указать все файлы:

go run main.go employee.go

Но вы почти всегда должны использовать go installили go build(и предпочтительно первое, поскольку go buildвызывает путаницу при работе с неосновными пакетами)


спасибо за вклад @JimB! Я отредактировал переменные среды (я также забыл установить GOBIN), переместил свои файлы в правильное место, но все же, когда я пытаюсь зайти в intstall, я получаю ту же ошибку. Какие-либо предложения?
Juan M

Вы уверены, что других ошибок нет? Ваш файл employee.go не может быть скомпилирован как есть. В противном случае мне нужно точно видеть , что вы делаете. Точные пути, вызов и т. Д.
JimB

8
Или сделайте $ go run * .go
Пуран

выполнение run $ go run *.goбыло бы сокращением вместо запуска всех файлов
offerni

61

У меня была такая же проблема в GoLand (это Intellij IDEA для Go), и я нашел решение. Вам нужно изменить Run kindс Fileна Packageили Directory. Вы можете выбрать это из раскрывающегося списка, если войдете в Run/EditКонфигурации.

Например: для пакета ~/go/src/a_packageиспользуйте a Package pathof a_packageи a Directoryof ~/go/src/a_packageи Run kindof Packageor Directory.


1
Спасибо, это то, что я искал. Обратите внимание, что ваш ответ касается Intellij IDEA.
kivagant

13

Если вы используете go run, сделайте go run *.go. Он автоматически найдет все файлы go в текущем рабочем каталоге, скомпилирует и затем запустит вашу основную функцию.


Есть ли недостатки в том, чтобы сделать это таким образом? Это кажется самым простым ответом на вопрос OP.
Stavros_S 04


8

Вы можете попробовать один из следующих:

Способ 1 :

  • Предположим, что название вашего проекта MyProject
  • Иди на свой путь, беги go build
  • Будет создан исполняемый файл в качестве имени вашего проекта («MyProject»).
  • Затем запустите исполняемый файл, используя ./MyProject

Вы можете выполнить оба шага одновременно, набрав go build && ./MyProject. Файлы Go package mainкомпилируются в исполняемый файл.

Способ 2 :

  • Просто беги go run *.go. Он не создает никаких исполняемых файлов, но работает.

3

Если вы хотите вызвать функцию из другого файла go и используете Goland, найдите опцию «Изменить конфигурацию» в меню «Выполнить» и измените тип выполнения с «Файл» на «Каталог». Он очищает все ошибки и позволяет вызывать функции из других файлов go.


1

Я столкнулся с той же проблемой Go11, просто хотел поделиться, как я решил ее, помогая другим на случай, если они столкнутся с той же проблемой.

У меня был проект Go снаружи $GOPATH , поэтому мне пришлось включить GO111MODULE=onэту опцию без включения этой опции, это даст вам эту проблему; даже если вы попытаетесь собрать или протестировать все, packageиначе directoryэто не будет решено безGO111MODULE=on


1

вам следует использовать модули go сейчас, если вы не следуете Как писать код go

С модулем go вам не нужно помещать код в файл $ GOPATH / src. он может жить и в любом другом месте.

Вы можете переместить код в другой каталог, например / employee. Чтобы он работал, сразу в каталоге сотрудников инициализируйте модуль go.

go mod init example.com/employee

0

go run .запустит все ваши файлы. Точка входа - это функция, main()которая должна быть уникальной для mainпакета.

Другой вариант - собрать двоичный файл go buildи запустить его.


0

Просто используйте команду go run *.goдля выполнения всех файлов go в вашем пакете!


Ответ похож на ответ @Paul Razvan Berg
Chris Catignani

-1

Если ваша исходная папка имеет структуру / go / src / blog (предполагается, что исходная папка называется blog).

  1. cd / go / src / blog ... (cd в папке с вашим пакетом)
  2. иди установи
  3. блог

Это должно запускать все ваши файлы одновременно, вместо того, чтобы вам приходилось перечислять файлы вручную или «отбивать» метод в командной строке.


Вы это понимаете go installи go buildразные? И исполняемый файл вызывается с использованием, ./<executable>а не blog. Поскольку вы использовали go installего в своем GOPATH/bin(даже добавленном к вашему $ PATH), и поэтому он просто blogработает для вас.
shmsr
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.