float64 中的字符串转换导致索引超出范围?

index out of range caused by string conversion in float64?

我是 Golang 的新手,我遇到了索引超出范围的问题,我已经记录了这一点,但在我的情况下仍然无法真正弄清楚是什么原因造成的,这是它检测到的代码错误:

func stringToPunto(lines []string)(punti []Punto, err error){
    for _, l := range lines {
        parts := strings.Split(l, ";")
        x, err := strconv.ParseFloat(parts[1], 64)
        
        if err != nil {
            return nil, fmt.Errorf("impossibile convertire l'ascissa: %w", err)
        }
        
        y, err := strconv.ParseFloat(parts[2], 64)
        
         if err != nil {
            return nil, fmt.Errorf("Impossibile convertire l'ordinata: %w", err)
        }
        
        punti = append(punti, Punto{
            etichetta: parts[0],
            x:         x,
            y:         y,
        })
    }
    return punti, nil
}

这是我遇到的错误:

panic: runtime error: index out of range

goroutine 1 [running]:
main.stringToPunto(0xc00001a0c0, 0x4, 0x4, 0x1, 0x0, 0x0, 0x2, 0x4)
        /home/main.go:40 +0x495
main.main()
        /home/main.go:128 +0x321

如果您想在 go 的 playground 上查看完整代码,这里有一个 link: https://go.dev/play/p/KQoRovuFXEo

我认为它无法在 float64 中解析它,这可能是因为该元素在我的上下文中不存在,或者我正在尝试访问错误中所说的超出范围的内容,但我真的可以理解不知道如何解决它,有人可以开玩笑地解释为什么会发生这种情况以及我该如何纠正它吗?

欢迎使用 Whosebug!您需要进行一些更改。我猜“soglia”正在请求将要输入的总点数。

您的代码请求点数,但未能将指针传递给将保存点数的变量。以下将在您的 main() 函数中解决此问题:

fmt.Scanln(&soglia)

注意变量前的&。 Scanln 函数采用指针参数。您传递了一个字符串 float64。 Scanln 无法将输出读入任何内容,因此它将输入留在输入队列中,当您开始输入点时会使用它。我怀疑如果你从 Scanln 检查错误代码,你会发现一个错误。我没有测试过。

所以,第一个点是一个数字,而不是一对数字。

其次,最好添加有关如何输入数字的说明。我花了一段时间才弄清楚我需要用分号分隔数字。 ;。您可以将此添加到 main() 函数中的 for 语句中:

fmt.Println("Please enter a series of x;y<enter> points.  Leave a blank line when you have entered all points.")

我不确定这行的目的是什么:

etichetta: parts[0],

似乎把你的 punti 结构弄乱了,但我可能不明白其意图。

终于在其他编码中看到了这个赋值类。我不明白为什么要求您在输入点数之前计算点数。您的追加调用为每个点分配 space 并在每次追加调用时增加 space。

此外,循环基于空行终止,但基于点数。因此,要么在扫描点的 for 循环中添加一个限制,要么完全删除“soglia”变量:-)

当然,您的作业可能需要 soglia 变量。如果是这种情况,您可以考虑这样的 for 循环:

 var soglia int.   // Declare it as an int.  

 ...

 fmt.Println("Please enter a series of x;y<enter> points.  Leave a blank line when you have entered all points.")
 for i := 0; i < soglia; i++ {
    scanner.Scan()
    line := scanner.Text()
    if len(line) == 0 {
        // If you use this, you would have to reset soglia
        soglia = i
        fmt.Printf("You did not enter the requested number of points.\n. soglia has been reset to %d.", soglia)
        break
    }
    lines = append(lines, line)
}