Распространенные грамматические ошибки в Go
1. Открывающие фигурные скобки нельзя размещать на отдельной строке.
код ошибки:
package main
import "fmt"
func main()
{
fmt.Println("hello world!")
}
Ошибка компиляции:
./main.go:5:6: missing function body for "main"
./main.go:6:1: syntax error: unexpected semicolon or newline before {
Правильный код:
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}
2. Неиспользуемые переменные
Если у вас есть неиспользуемые локальные переменные, код не скомпилируется.
Если вы присвоите новое значение неиспользуемой переменной, код все равно не скомпилируется. Вам нужно где-то использовать эту переменную, чтобы компилятор успешно компилировался.
код ошибки:
package main
var gvar int
func main() {
var one int
two := 2
var three int
three = 3
}
Ошибка компиляции:
./main.go:6:6: one declared and not used
./main.go:7:9: two declared and not used
./main.go:8:6: three declared and not used
Правильный код:
package main
import "fmt"
func main() {
var one int
_ = one
two := 2
fmt.Println(two)
var three int
three = 3
one = three
var four int
four = four
}
// Вы также можете закомментировать или удалить неиспользуемые переменные
3. Неиспользованный импорт
Если вы импортируете пакет без использования каких-либо его функций, интерфейсов, структур или переменных, код не скомпилируется.
Если вам действительно нужно импортировать пакет, вы можете добавить знак подчеркивания «_» в качестве имени пакета, чтобы избежать сбоя компиляции. Маркер подчеркивания используется для введения, но не используется.
код ошибки:
package main
import (
"fmt"
"log"
"time"
)
func main() {
}
```go
Ошибка компиляции:
./main.go:4:2: imported and not used: “fmt”
./main.go:5:2: imported and not used: “log”
./main.go:6:2: imported and not used: “time”
Правильный код:
```go
package main
import (
_ "fmt"
"log"
"time"
)
var _ = log.Println
func main() {
_ = time.Now
}
// Вы также можете удалить или закомментировать неиспользуемый импорт
4. «: =» Простое объявление переменной можно использовать только внутри функции.
код ошибки:
package main
myvar := 1
func main() {
}
Ошибка компиляции:
./main.go:3:1: syntax error: non-declaration statement outside function body
Правильный код:
package main
var myvar = 1
func main() {
}
5. Используйте краткие объявления для многократного объявления переменных.
Вы не можете повторно объявлять переменную в одном объявлении, но это разрешено в объявлении с несколькими переменными, где должна быть включена по крайней мере одна новая объявленная переменная.
Повторяющиеся переменные должны находиться в одном блоке кода, иначе вы получите скрытую переменную.
код ошибки:
package main
func main() {
one := 0
one := 1
}
Ошибка компиляции:
./main.go:5:6: no new variables on left side of :=
Правильный код:
package main
func main() {
one := 0
one, two := 1, 2
one, two = two, one
}
6. В названии языка Go учитывается регистр.
код ошибки:
package main
import "fmt"
func main() {
fmt.println("Hello world")
}
// Все следующие коды неверны:
// Package main
// iMport "fmt"
// import "Fmt"
// Func main() {}
// Fmt.Println
// fmt.println
Ошибка компиляции:
./main.go:6:2: cannot refer to unexported name fmt.println
./main.go:6:2: undefined: fmt.println
Правильный код:
package main
import "fmt"
func main() {
fmt.Println("Hello world")
}
7. Точка с запятой в языке Go.
код ошибки:
package main
import "fmt"
func main() {
fmt.Println("Hello world") fmt.Println("Hi again")
}
Ошибка компиляции:
./main.go:6:29: syntax error: unexpected fmt at end of statement
Правильный код:
package main
import "fmt"
func main() {
fmt.Println("Hello world")
// Чтобы решить вышеуказанные проблемы, вы можете поместить два вышеуказанных оператора в две строки
fmt.Println("Hi again")
// Вы можете заканчивать два оператора точкой с запятой
fmt.Println("Hello world");fmt.Println("Hi again")
test()
}
func test() {
// Таким образом, в языке Go точка с запятой может быть сохранена. Если вам необходимо ее использовать, вы можете добавить ее без ошибок.
fmt.Println("Hello world");fmt.Println("Hi again");
};
8. Недопустимая точка с запятой в языке Go.
код ошибки:
package main
import "fmt";;
func main() {
fmt.Println("Hello world")
}
Ошибка компиляции:
./main.go:3:14: syntax error: non-declaration statement outside function body
Правильный код:
package main
import "fmt";
func main() {
fmt.Println("Hello world")
}
9. Обратите внимание на область видимости переменных в языке Go.
код ошибки:
package main
var num int
func main() {
str := "hello world"
if true {
var b bool
}
println(num)
println(str)
println(b)
}
Ошибка компиляции:
./main.go:12:10: undefined: b
Правильный код:
package main
var num int
func main() {
str := "hello world"
if true {
var b bool
println(b)
}
println(num)
println(str)
}
10. Случайное скрытие переменной
Синтаксис краткого объявления переменных настолько удобен (особенно для разработчиков, которые использовали динамические языки), что люди легко могут рассматривать его как обычную операцию присваивания. Если вы сделаете эту ошибку в новом блоке кода, ошибок компиляции не будет, но ваше приложение не будет делать то, что вы ожидаете.
package main
import "fmt"
func main() {
x := 1
fmt.Println(x) // 1
{
fmt.Println(x) // 1
x := 2
fmt.Println(x) // 2
}
fmt.Println(x) // 1
}
результат операции:
1
1
2
1
Даже для опытных разработчиков Go это обычная ловушка, но ее трудно обнаружить.
Вы можете использовать команду vet, чтобы найти некоторые из этих проблем. По умолчанию ветеринар не будет выполнять такие проверки, вам нужно установить параметр -shadow:
Команда: go tool vet -shadow your_file.go
go tool vet -shadow main.go
main.go:10: declaration of "x" shadows declaration at main.go:6
11. Без использования явных типов нельзя использовать «nil» для инициализации переменных.
Флаг nil используется для представления «нулевого значения» интерфейсов, функций, карт, срезов и каналов. Если вы не укажете тип переменной, компилятор не сможет скомпилировать ваш код, потому что он не может угадать конкретный тип.
код ошибки:
package main
func main() {
var x = nil
_ = x
}
Ошибка компиляции:
./main.go:4:6: use of untyped nil
Правильный код:
package main
func main() {
var x interface{} = nil
_ = x
}
12. Используйте нулевые фрагменты и карты.
Добавление элементов в нулевой фрагмент — это нормально, но выполнение того же действия для карты вызовет панику во время выполнения.
Правильный код:
package main
func main() {
var s []int
s = append(s, 1)
}
код ошибки:
package main
import (
"fmt"
)
func main() {
var m map[int]int
m[1] = 1
fmt.Println(m)
}
Ошибка выполнения:
panic: assignment to entry in nil map
Правильный код:
package main
import (
"fmt"
)
func main() {
var m map[int]int
m = make(map[int]int)
m[1] = 1
fmt.Println(m)
}
13. Вместимость карты
карта имеет только операцию len, без операции ограничения
код ошибки:
package main
import (
"fmt"
)
func main() {
m := map[int]string{1: "a", 2: "b", 3: "c"}
cap := cap(m)
fmt.Println(cap)
}
Ошибка компиляции:
./main.go:9:12: invalid argument m (type map[int]string) for cap
Правильный код:
package main
import (
"fmt"
)
func main() {
m := map[int]string{1: "a", 2: "b", 3: "c"}
len := len(m)
fmt.Println(len)
}
14. Строка не будет нулевой.
Это место, на которое следует обратить внимание разработчиков, которые часто используют nil для выделения строковых переменных.
package main
func main() {
var x string = nil
if x == nil {
x = "default"
}
}
Ошибка компиляции:
./main.go:4:6: cannot use nil as type string in assignment
./main.go:5:7: invalid operation: x == nil (mismatched types string and nil)
Правильный код:
package main
func main() {
var x string
if x == "" {
x = "default"
}
}
$ cat f3.go
package main
func f(x int) int {
retrun x
}
$ go run f3.go
# command-line-arguments
./f3.go:4:9: syntax error: unexpected x at end of statement
$ gofmt f3.go
f3.go:4:9: expected ';', found x
f3.go:5:3: expected '}', found 'EOF'
I would usually not mind if go/parser is worse than the compiler’s parser at giving useful errors. However, now that vet always runs with test, it’s vet that reports syntax errors to me when I run go test
. This particular error (the more confusing one) had me scratching my head for a minute, before I realised the typo.
Should this be fixed in go/parser, or should something else be done, such as using the compiler’s syntax package to replace go/parser’s syntax errors?
/cc @griesemer
mvdan
added
the
NeedsDecision
Feedback is required from experts, contributors, and/or the community before a change can be made.
label
Mar 6, 2018
I agree that the change to run vet always changes what errors one sees, and after all the work put into getting excellent errors from the compiler, it’s a shame to go back to the less precise ones from go/parser.
But: vet is running in parallel with the compiler, so I think it makes sense to hold off printing errors from vet until the compiler has completed. If the compile fails, drop the noise from vet. That way we only see vet errors if something actually builds.
That makes sense. That’s the sort of thing I was suggesting as an alternative to having to improve go/parser’s errors.
I’d like to see the new syntax package taking the place of go/parser, eventually. Then all tools (including the compiler) will use the same front-end code, with identical behavior and errors. But I don’t want to rush this process because once package syntax is exposed (not internal) we cannot change its API anymore. Also, all other go/* packages would have to be adjusted which — while not hard — a time-consuming and error-prone process.
But it should be fairly straight-forward to port back this specific error message if need be But @r’s suggestion is a better one and solves the more general problem.
Great — I’ll give Rob’s fix a try. Thank you both for your input.
@griesemer after repurposing this issue to be about the go command, do you want to open another issue about improving go/parser’s error?
mvdan
changed the title
go/parser: lacks «unexpected X at end of statement» error
cmd/go: test gives go/parser’s syntax errors, which are sometimes worse than the compiler’s
Mar 7, 2018
Actually, I was wrong — my particular case had nothing to do with vet. My problem was coming from go test
using go/parser
directly in loadTestFuncs
. Skipping this error is a bit tricky, since this happens much earlier than the build action. I’m no longer sure that a change in test is the right fix.
@mvdan I’ll assign this to me and will look at the parser’s error message. But this is not urgent.
Indeed not urgent — also fine by me if it’s not fixed at all, as long as go/parser is replaced eventually.
gopherbot
removed
the
NeedsDecision
Feedback is required from experts, contributors, and/or the community before a change can be made.
label
Mar 12, 2018
It occurred to me that this issue is likely relevant to @findleyr’s recent work
Yes, @findleyr is actively working on the parser and I suspect sooner or later the go/parser will produce much better error messages.
Obsidian2010 0 / 0 / 0 Регистрация: 25.09.2012 Сообщений: 21 |
||||
1 |
||||
20.10.2015, 21:43. Показов 8581. Ответов 7 Метки нет (Все метки)
Подскажите, в чём ошибка?
__________________
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
20.10.2015, 21:43 |
Ответы с готовыми решениями: Ошибка Statement expected but end of file found Ошибка: project1.lpr(1,1) Fatal: Syntax error, «BEGIN» expected but «end of file» found Ошибка: Syntax error, «BEGIN» expected but «end of file» found {$mode objfpc}{$H+} interface uses Ошибка: syntax error, unexpected end of file, expecting end Для любого целого k обозначим количество цифр… 7 |
15131 / 6405 / 1730 Регистрация: 24.09.2011 Сообщений: 9,999 |
|
20.10.2015, 21:49 |
2 |
Ошибка Syntax error Expected: end of statement Нет ошибки, программа компилируется и работает со значениями по умолчанию.
0 |
0 / 0 / 0 Регистрация: 25.09.2012 Сообщений: 21 |
|
20.10.2015, 21:51 [ТС] |
3 |
а у меня прерывается программа, указывая на ошибку syntax error
0 |
15131 / 6405 / 1730 Регистрация: 24.09.2011 Сообщений: 9,999 |
|
20.10.2015, 22:02 |
4 |
а у меня прерывается программа, указывая на ошибку syntax error Напишите хотя бы — в какой строке ошибка? В VBA какого приложения Вы работаете?
0 |
0 / 0 / 0 Регистрация: 25.09.2012 Сообщений: 21 |
|
20.10.2015, 22:42 [ТС] |
5 |
Напишите хотя бы — в какой строке ошибка? В VBA какого приложения Вы работаете? Function Площадь(n As Double, k As Double) As Double — в этой строке. А эту строку выделяет красным y = Atn(n/k*Sqr(Abs(n-k)))*3^(n*k)/(Exp(-1/Tan(n))*Log(Abs(n-k)))
0 |
15131 / 6405 / 1730 Регистрация: 24.09.2011 Сообщений: 9,999 |
|
20.10.2015, 22:55 |
6 |
Obsidian2010, м-да, чудеса Код 100% рабочий (в Excel 2007), попробуйте скопировать его из своего поста, вставить в новую книгу и запустить.
0 |
0 / 0 / 0 Регистрация: 25.09.2012 Сообщений: 21 |
|
20.10.2015, 23:32 [ТС] |
7 |
http://rghost.ru/8FwjgRSBS
0 |
15131 / 6405 / 1730 Регистрация: 24.09.2011 Сообщений: 9,999 |
|
20.10.2015, 23:53 |
8 |
Obsidian2010, работает Миниатюры
1 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
20.10.2015, 23:53 |
Помогаю со студенческими работами здесь Ошибка «project1.lpr(35,0) Fatal: Syntax error, «BEGIN» expected but «end of file» found» Ошибка «Syntax error, «BEGIN» expected but «end of file» found» Ошибка «Fatal: Syntax error, «BEGIN» expected but «END» found» {$mode objfpc}{$H+} interface uses Ошибка [Error] Unit5.pas(53): Statement expected but ‘PROCEDURE’ found interface uses Ошибка: Parse error: syntax error, unexpected end of file in Parse error: syntax error,… Ошибка в форме обратной связи: Parse error: syntax error, unexpected $end Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 8 |