英文:
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
语句有三种形式:
- 单个条件表达式
- 三个语句版本,包括初始化语句、条件和后置语句
- 范围子句
你的语句不符合这些形式。很可能编译器认为你使用的是第一种形式,并在arrayPointer >= 0
后面没有{
时报错。你可以通过改为第二种形式来修复这个问题:
for ; arrayPointer >= 0 ; arrayPointer-- {
(或者将arrayPointer
的初始化语句作为for
语句的第一部分)。
英文:
From the spec, there are three forms for a for
statement:
- a single conditional expression
- the three statement version giving an init statement, condition and post statement
- 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 "fmt"
func main() {
inString := "I am a string"
// 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 < 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))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论