Go中的奇怪编译器错误

huangapple go评论100阅读模式
英文:

Weird Compiler Errors in Go

问题

当我运行以下代码(它应该将字符串的内容反转),编译器会报错。

  1. package main
  2. import "fmt"
  3. func main(){
  4. argString := "I am a string"
  5. arrayPointer := len(argString)
  6. outputString := "string"
  7. for arrayPointer >= 0 ; arrayPointer-- {
  8. outputString := fmt.Sprintf("%s%s", outputString, argString[arrayPointer])
  9. }
  10. }

它会抛出以下错误:

  1. prog.go:9: syntax error: missing { after for clause
  2. prog.go:12: syntax error: unexpected }
  3. [process exited with non-zero status]

我以前使用过这种语法(除非我漏掉了什么),从来没有看到过这种错误。我漏掉了什么?

英文:

When I run the following code (it's supposed to reverse the contents of a string), I get strange errors from the compiler.

  1. package main
  2. import "fmt"
  3. func main(){
  4. argString := "I am a string"
  5. arrayPointer := len(argString)
  6. outputString := "string"
  7. for arrayPointer >= 0 ; arrayPointer-- {
  8. outputString := fmt.Sprintf("%s%s", outputString, argString[arrayPointer])
  9. }
  10. }

It throws the following errors:

  1. prog.go:9: syntax error: missing { after for clause
  2. prog.go:12: syntax error: unexpected }
  3. [process exited with non-zero status]

I've used this syntax before (unless I'm missing something), and I've never seen errors from it. What am I missing?

答案1

得分: 6

从规范来看,for语句有三种形式:

  1. 单个条件表达式
  2. 三个语句版本,包括初始化语句、条件和后置语句
  3. 范围子句

你的语句不符合这些形式。很可能编译器认为你使用的是第一种形式,并在arrayPointer >= 0后面没有{时报错。你可以通过改为第二种形式来修复这个问题:

  1. for ; arrayPointer >= 0 ; arrayPointer-- {

(或者将arrayPointer的初始化语句作为for语句的第一部分)。

英文:

From the spec, there are three forms for a for statement:

  1. a single conditional expression
  2. the three statement version giving an init statement, condition and post statement
  3. a range clause.

Your statement doesn't match any of these. Most likely the compiler has decided that you are using (1), and errors out when there isn't a { after arrayPointer >= 0. You can fix this by changing to case (2):

  1. for ; arrayPointer >= 0 ; arrayPointer-- {

(or using the arrayPointer initialisation statement as the first part of the for statement).

答案2

得分: 1

这段代码除了 for 语句的错误之外还有一些其他错误(例如,你的 arrayPointer 被初始化为 len(argString) 而不是 len(argString)-1,所以你会立即遇到越界违规)。

无论如何,我认为这是你尝试的一个优化的、惯用的版本:

  1. package main
  2. import "fmt"
  3. func main() {
  4. inString := "I am a string"
  5. // 使用一个输出缓冲区,因为(1)字符串是不可变的,
  6. // (2)向字符串追加会从现有字符串和新追加的部分创建一个新字符串。
  7. // 这种方法一次性分配了所有必要的内存。
  8. // len(inString) 次分配 vs 1 次分配。
  9. outBuffer := make([]uint8, len(inString))
  10. for i := 0; i < len(outBuffer); i++ {
  11. // 将字符串的倒数第 i 个字符复制到 outBuffer 的第 i 个位置
  12. outBuffer[i] = inString[len(inString)-i-1]
  13. }
  14. fmt.Println(string(outBuffer))
  15. }

希望对你有帮助!

英文:

This code has a few errors besides the malformed for statement (e.g., your arrayPointer is initialized to len(argString) rather than len(argString)-1, so you'll hit an out-of-bounds violation right away).

Anyway, I think this an optimized, idiomatic version of what you're attempting:

http://play.golang.org/p/fFCf3L8ov9

  1. package main
  2. import &quot;fmt&quot;
  3. func main() {
  4. inString := &quot;I am a string&quot;
  5. // use an output buffer because (1) strings are immutable and
  6. // (2) appending to strings creates a new string from the existing
  7. // string and its new appendix. This method allocates
  8. // all the necessary memory 1 time. len(inString) allocations
  9. // vs 1 allocation.
  10. outBuffer := make([]uint8, len(inString))
  11. for i := 0; i &lt; len(outBuffer); i++ {
  12. // copy the i-th character from the end of the string
  13. // into the i-th position of outBuffer
  14. outBuffer[i] = inString[len(inString)-i-1]
  15. }
  16. fmt.Println(string(outBuffer))
  17. }

huangapple
  • 本文由 发表于 2014年6月23日 10:11:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/24357576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定