Go中的奇怪编译器错误

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

Weird Compiler Errors in Go

问题

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

package main
import "fmt"
func main(){

    argString := "I am a string"
    arrayPointer := len(argString)
    outputString := "string"
   
    for arrayPointer >= 0 ; arrayPointer-- {
        outputString := fmt.Sprintf("%s%s", outputString, argString[arrayPointer])
    }
}

它会抛出以下错误:

prog.go:9: syntax error: missing { after for clause
prog.go:12: syntax error: unexpected }
[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.

package main
import "fmt"
func main(){

    argString := "I am a string"
    arrayPointer := len(argString)
    outputString := "string"
   
    for arrayPointer >= 0 ; arrayPointer-- {
        outputString := fmt.Sprintf("%s%s", outputString, argString[arrayPointer])
    }
}

It throws the following errors:

prog.go:9: syntax error: missing { after for clause
prog.go:12: syntax error: unexpected }
[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后面没有{时报错。你可以通过改为第二种形式来修复这个问题:

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):

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,所以你会立即遇到越界违规)。

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

package main

import "fmt"

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

    fmt.Println(string(outBuffer))
}

希望对你有帮助!

英文:

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

package main

import &quot;fmt&quot;

func main() {
	inString := &quot;I am a string&quot;
	
	// use an output buffer because (1) strings are immutable and
	// (2) appending to strings creates a new string from the existing
	// string and its new appendix. This method allocates
	// all the necessary memory 1 time. len(inString) allocations
    // vs 1 allocation.
	outBuffer := make([]uint8, len(inString))
	for i := 0; i &lt; len(outBuffer); i++ {
	    // copy the i-th character from the end of the string
		// into the i-th position of outBuffer
		outBuffer[i] = inString[len(inString)-i-1]
	}

	fmt.Println(string(outBuffer))
}

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:

确定